맨위로가기 타임라인 바로가기

러스트 (프로그래밍 언어)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
타임라인 바로가기

1. 개요

러스트(Rust)는 안전성, 속도, 동시성을 강조하는 다중 패러다임 프로그래밍 언어이다. 2006년 모질라 직원 그레이든 호어의 개인 프로젝트로 시작되었으며, 이후 모질라의 후원을 받아 발전했다. 2015년 안정 버전 1.0이 출시되었고, 현재는 러스트 재단에서 관리한다. 러스트는 소유권, 차용 검사기, 라이프타임과 같은 기능을 통해 메모리 안전성을 보장하며, C/C++와 유사한 성능을 제공한다. 웹 브라우저, 운영 체제, 웹 서비스 등 다양한 분야에서 채택되고 있으며, 카고(Cargo)를 통해 빌드 및 패키지 관리를 지원한다.

더 읽어볼만한 페이지

  • 2012년 개발된 프로그래밍 언어 - 줄리아 (프로그래밍 언어)
    줄리아는 2012년에 공개된 고수준 프로그래밍 언어로, 다중 디스패치, 동적 타입 시스템, C와 유사한 성능을 제공하며, 수치 계산, 과학 기술 계산 등에 활용된다.
  • 2012년 개발된 프로그래밍 언어 - 타입스크립트
    타입스크립트는 마이크로소프트에서 개발한 자바스크립트의 상위 집합으로, 정적 타입 지정, 타입 추론 등의 기능을 제공하여 코드의 안정성과 가독성을 높이는 언어이다.
  • 코드 예시에 관한 문서 - 순서도
    순서도는 컴퓨터 알고리즘이나 프로세스를 시각적으로 표현하는 도구로, 흐름 공정 차트에서 기원하여 컴퓨터 프로그래밍 분야에서 알고리즘을 설명하는 데 사용되며, 다양한 종류와 소프트웨어 도구가 존재한다.
  • 코드 예시에 관한 문서 - 람다 대수
    람다 대수는 알론조 처치가 수학기초론 연구를 위해 도입한 형식 체계로, 초기 체계의 모순 수정 후 유형 없는 람다 대수와 단순 유형 람다 대수가 발표되었으며, 프로그래밍 언어와의 관계가 명확해지면서 컴퓨터 과학과 언어학에서 중요한 위치를 차지하며 함수형 프로그래밍 언어의 기반이 되었고, 튜링 완전성을 가지는 등 다양한 분야에 응용된다.
  • 패턴 매칭 프로그래밍 언어 - AWK
    AWK는 1977년에 개발된 텍스트 처리 및 프로그래밍 언어로, 유닉스 환경에서 텍스트 처리를 위해 설계되었으며 정규 표현식 처리 기능을 통해 텍스트 분석, 데이터 추출, 보고서 생성 등 다양한 작업을 수행한다.
  • 패턴 매칭 프로그래밍 언어 - 하스켈
    하스켈은 해스켈 커리의 이름을 딴 순수 함수형 프로그래밍 언어로, 여러 함수형 언어 통합 노력의 결과로 탄생하여 느긋한 계산법, 패턴 매칭, 타입 클래스, 모나드 등의 특징을 가지며 GHC가 표준 구현체로 사용된다.
러스트 (프로그래밍 언어) - [IT 관련 정보]에 관한 문서
기본 정보
러스트 로고; 톱니바퀴 안에 있는 대문자 R
러스트 로고
설계자그레이든 호아레
개발자러스트 팀
출시일2015년 5월 15일
파일 확장자.rs, .rlib
영향받은 언어Alef
BETA
CLU
C#
C++
Cyclone
Elm
Erlang
Haskell
Hermes
Limbo
Mesa
Napier
Newsqueak
NIL
OCaml
Ruby
Sather
Scheme
Standard ML
Swift
영향을 주는 언어Idris
Project Verona
Spark
Swift
V
Zig
패러다임
프로그래밍 패러다임병행
함수형
제네릭
명령형
구조적
유형 체계
유형 체계어파인
추론
명목적
정적
강한
구현체
구현체rustc
플랫폼 및 운영 체제
플랫폼크로스 플랫폼
운영 체제크로스 플랫폼
라이선스
라이선스MIT, 아파치 2.0

2. 역사

Rust 1.13 이전 버전에서는 셸 스크립트로 구현된 rustup.sh가 공개되었다[212]。이와 병행하여 Rust 언어로 구현된 동일한 기능을 제공하는 rustup.rs의 개발이 진행되었으며, Rust 1.14 버전에서 rustup.sh는 더 이상 사용되지 않게 되었고[213], Rust 1.14 버전 이후부터 rustup.rs가 공식 릴리스로 제공되고 있다[214][215]

모질라(Mozilla) 직원 그레이든 호어(Graydon Hoare)는 2006년부터 개인 프로젝트로 러스트 개발을 시작했다.[10] 호어는 러스트의 이름이 "생존을 위해 지나치게 설계된" 녹병 균류에서 따왔다고 밝혔다.[10] 2009년까지는 모질라 내 다른 사람들에게 공개되지 않았고, 호어의 여가 시간에 작성되었다.[11]

호어는 2009년경 모질라의 소규모 그룹이 프로젝트에 관심을 보이면서 이 언어에 대해 이야기하기 시작했다.[12] 그는 CLU(1974), BETA(1975), Mesa(1977), NIL(1981), Erlang(1987), 뉴스퀴크(Newsqueak) (1988), 네이피어(Napier88) (1988), 헤르메스(Hermes) (1990), Sather(1990), 알레프(Alef) (1992), 림보(1996)와 같은 언어들에서 영향을 받았다고 언급하며, "많은 오래된 언어가 새로운 언어보다 낫다"고 평가했다. 그리고 이 언어를 "과거의 기술이 미래를 구원하기 위해 온 것"이라고 묘사했다.[11][12] 초기 러스트 개발자 마니쉬 고레가오카(Manish Goregaokar) 역시 러스트가 "대부분 수십 년 된 연구"를 기반으로 한다고 설명했다.[10]

캘리포니아 마운틴뷰에 있는 모질라 재단(Mozilla Foundation) 본사


초창기 러스트의 컴파일러는 약 38,000줄의 OCaml로 작성되었다.[11][13] 초기에는 명시적인 객체 지향 프로그래밍 (나중에 제거됨)과, 변수의 상태 변경을 추적할 수 있는 타입 상태 시스템과 같은 기능을 포함했다. 함수는 기본적으로 순수 함수였으며, 명시적인 주석 없이는 부작용이 허용되지 않았다.[11]

모질라(Mozilla)는 2009년부터 Rust 개발에 관여하기 시작했으며[230][231], 2010년 모질라 서밋에서 처음 공개되었다[232]。초창기 Rust 컴파일러OCaml 언어로 만들어진 컴파일러(rustboot)가 사용되었지만[233], 2010년에는 Rust 언어 자체로 Rust 컴파일러를 만드는 셀프 호스팅으로 전환된 컴파일러(rustc) 개발이 시작되었고[234], 이듬해에는 부트스트랩 문제를 해결한 첫 번째 완성품이 완성되었다[235]。이때부터 Rust 컴파일러는 컴파일 기반으로 LLVM을 사용하게 되었다[236]

모질라는 2009년에 러스트 프로젝트를 공식적으로 후원했다.[10] 브렌던 아이크를 비롯한 다른 임원들은 러스트를 안전한 웹 브라우저 엔진에 사용할 가능성에 주목하여, 패트릭 월튼, 니코 마차키스, 펠릭스 클록, 마니쉬 고레가오카를 포함한 엔지니어들을 프로젝트에 배치했다. 개발자들이 사용하던 회의실은 "너드 동굴"이라고 불렸으며, 문 밖에 표지판이 걸려 있었다.[10]

이 기간 동안, 초기 OCaml 컴파일러에서 LLVM 기반의 셀프 호스팅 컴파일러로 변경하는 작업이 진행되었다.[14] Rust 소유권 시스템도 2010년까지 구축되었다.[10] 2011년에는 자전거 체인링을 기반으로 한 러스트 로고가 개발되었다.[16]

첫 번째 공개 릴리스인 Rust 0.1은 2012년 1월에 출시되었다.[14] 2010년대 초반에는 모질라 외부 및 미국 외부의 오픈 소스 자원봉사자들의 참여가 증가했다. 모질라에서는 임원들이 향후 10년 동안 Rust에 전념할 12명 이상의 엔지니어를 고용하게 되었다.[10]

러스트는 2012년부터 2015년까지 타입 시스템에 큰 변화를 겪었다. 타입 상태 시스템이 제거되고, 다른 언어 기능이 통합되었으며, 가비지 컬렉터가 제거되었다.[11][10] 소유권 시스템을 통한 메모리 관리가 점진적으로 확장되어 메모리 관련 버그를 방지했다. 2013년까지 가비지 컬렉터 기능은 거의 사용되지 않아 제거되었다.[10] 2013년 3월에는 명시적인 주석으로 선언되던 순수 함수가 제거되었다.[17] 언어 단순화를 위해 채널과 다양한 포인터 유형에 대한 특수 구문 지원이 제거되었다.[11]

객체 시스템은 러스트 0.2에서 0.4 버전에 걸쳐 많은 변화를 겪었다. 0.2 버전에서는 클래스가 도입되었고, 0.3 버전에서는 소멸자와 인터페이스가 도입되었다. 0.4 버전에서는 trait 기능이 도입되면서 인터페이스는 trait와 통합되었고, class는 제거되었다.[242]

0.4 버전 이전에는 정적 타입 검사와 더불어 타입 상태 분석 기능을 지원했다. 타입 상태 분석 기능은 선언문 전후에 `check` 키워드를 사용하여 해당 선언문이 의도대로 동작하는지 컴파일 시에 검사하는 기능이었으나, 실질적으로 거의 사용되지 않아 제거되었다.[240][241]

코어 메모리 모델은 0.9 버전부터 0.11 버전 사이에 단순화 과정을 거쳤다. 힙 메모리형 `~`과 가비지 컬렉션형 `@`의 두 가지 빌트인 포인터형은 표준 라이브러리의 `Box`형과 `Gc`형으로 대체되었고, `Gc`형은 최종적으로 삭제되었다.[242]

러스트의 발전은 C++ 개발자 (기능의 낮은 수준 성능), 스크립트 언어 (Cargo 및 패키지 관리), 함수형 프로그래밍 (타입 시스템 개발) 출신 개발자들의 영향을 받았다.[11]

판정은 0.4 버전 이전의 기존 정적 타이핑 외에, 형 상태 시스템을 지원했다. 형 상태 시스템은 특별한 check 문을 사용하여 프로그램 문 전후의 형 결정을 모델링했다. C 언어 및 C++ 코드에서의 어서션과 마찬가지로, 프로그램 실행 중이 아닌 컴파일 시에 형 불일치를 감지한다. 형 상태의 개념은 Rust 특유의 것이 아니라, NIL에서 채용되었던 것이다.[240]

2014년 1월, ''Dr. Dobb's Journal''의 편집장 앤드류 빈스톡(Andrew Binstock)은 러스트가 C++의 경쟁자가 될 가능성에 대해 D, Go, Nim과 함께 언급했다. 빈스톡에 따르면, 러스트는 "매우 우아한 언어로 널리 여겨졌지만", 버전마다 급격하게 변경되어 채택이 늦어졌다.[18][243]

그레이든 호어(Graydon Hoare)는 2013년에 러스트에서 물러났다.[10] 초기 6명으로 구성된 "코어 팀"은 의견 요청 (RFC) 프로세스를 통해 보다 연합된 거버넌스 구조하에서 발전했다.[11] 코어 팀은 2016년까지 9명으로 늘어났으며, 1600개 이상의 RFC가 제안되었다.[11]

모질라(Mozilla)가 개발을 후원한 지 6년 만인 2015년 5월 15일에 첫 번째 안정적 릴리스인 러스트 1.0이 공개되었다.[10] 릴리스 1년 후, 러스트 컴파일러는 1,400명 이상의 기여자를 확보했으며, 러스트 패키지 관리 웹사이트 Crates.io에 5,000개 이상의 타사 라이브러리가 게시되었다.[11]

Servo 브라우저 엔진의 개발은 러스트와 병행하여 진행되었으며, 모질라삼성의 공동 자금 지원을 받았다.[19] 두 프로젝트 팀은 긴밀하게 협력하여 러스트의 새로운 기능은 Servo 팀에서 테스트하고 Servo의 새로운 기능은 러스트 팀에 피드백하는 데 사용되었다.[11]

모질라의 Servo 브라우저 엔진 초기 홈페이지


Servo의 첫 번째 버전은 2016년에 출시되었다.[10] 파이어폭스 웹 브라우저는 2016년(버전 45)부터 러스트 코드를 포함하여 출시되었지만,[11][20] Servo의 구성 요소는 2017년 9월(버전 57)에 Gecko 및 Quantum 프로젝트의 일부로 파이어폭스에 나타났다.[21]

1.0 이후 몇 년 동안 Rustfmt, 통합 개발 환경 통합, 정기적인 컴파일러 테스트 및 릴리스 주기, 커뮤니티 행동 강령, IRC 채팅을 통해 조직된 커뮤니티 토론을 포함하여 러스트 툴체인 생태계가 개선되었다.[11]

모질라 외부의 초기 채택은 삼성, 페이스북(현재 Meta Platforms), Dropbox 및 Tilde, Inc.(ember.js의 제작 회사)를 포함한 개별 프로젝트에서 이루어졌다.[11][10] 아마존 웹 서비스는 2020년에 뒤를 이었다.[10] 엔지니어들은 성능, 가비지 수집기 부재, 안전성 및 언어 작업의 즐거움을 채택 이유로 꼽았지만, 러스트가 새로운 기술이므로 위험한 선택임을 인정했다. 아마존 개발자들은 러스트가 포르투갈의 미뉴 대학교, 리스본 신대학교, 코임브라 대학교의 연구에서 밝혀진 바와 같이 자바로 작성된 유사한 코드보다 전력 소비가 절반밖에 되지 않으며 C 다음으로 효율적이라는 점을 언급했다.[10][22]

2015년 5월 16일, 안정 버전인 Rust 1.0이 출시되었다[244]。1.0 버전 이후, 안정 버전 및 베타 버전이 6주 간격으로 정기적으로 릴리스되고 있다[245]。또한 나이틀리 버전이 매일 릴리스되고 있다[246]。새로운 기능은 나이틀리 버전에서 개발이 진행되며, 베타 버전에서 동작이 검증되고 있다[247]

2016년 8월 2일에 릴리스된 Firefox 48에는 Rust로 다시 작성된 미디어 파서가 탑재되었으며, 모질라가 개발하고 있는 브라우저인 파이어폭스에서 Rust로 작성된 코드가 추가된 첫 번째 사례가 되었다.[248][249]

2016년 9월에 Rust는 Fedora 24의 표준 구성 요소에 추가되었으며, RPM의 패키지 관리 시스템을 사용하여 설치 작업이 용이해졌다[250]

모질라 재단코로나19 범유행으로 인한 구조조정으로 2020년 8월에 서보 팀을 해체하면서, 러스트의 미래에 대한 우려가 제기되었다.[23][24][25] 이에 러스트 코어 팀은 러스트 재단 설립 계획을 발표하고, 모든 상표와 도메인 이름 소유권 및 재정적 책임을 재단으로 이전하는 것을 목표로 하였다.[26]

2021년 2월 8일, 아마존 웹 서비스, 구글, 화웨이, 마이크로소프트, 모질라 재단 등 5개 회사가 러스트 재단 설립을 공식 발표하였다.[27][28] 초대 의장은 셰인 밀러가 맡았으며, 재단은 주요 러스트 기능을 개발하는 프로그래머에게 재정적 지원을 제공했다.[10] 2021년 4월 6일, 구글은 안드로이드 오픈 소스 프로젝트 내에서 C/C++의 대안으로 러스트를 지원한다고 발표했다.[29]

2021년 11월 22일, 커뮤니티 행동 강령 시행을 담당하는 중재 팀은 코어 팀의 책임 문제를 제기하며 사임했다.[30] 2022년 5월, 러스트 코어 팀, 다른 수석 프로그래머 및 러스트 재단 이사회 일부 구성원은 이 사건에 대응하여 거버넌스 개혁을 시행했다.[31]

2023년 4월 6일, 러스트 재단은 러스트 로고와 이름 사용 규칙을 포함한 새로운 상표 정책 초안을 게시했으나, 사용자 및 기여자의 부정적인 반응을 얻었다.[32]

러스트 파운데이션(Rust Foundation)은 러스트 프로그래밍 언어와 생태계를 관리하는 독립적인 비영리 조직으로, "좋은 소프트웨어는 행복하고 잘 지원되는 사람들에 의해 만들어집니다"라는 모토를 갖고 프로젝트를 관리하고 개발하는 유지 관리자를 지원하는 데 중점을 두고 있다.[303]

2. 1. 초기 (2006~2009)

모질라(Mozilla) 직원 그레이든 호어(Graydon Hoare)는 2006년부터 개인 프로젝트로 러스트 개발을 시작했다.[10] 호어는 러스트의 이름이 "생존을 위해 지나치게 설계된" 녹병 균류에서 따왔다고 밝혔다.[10] 2009년까지는 모질라 내 다른 사람들에게 공개되지 않았고, 호어의 여가 시간에 작성되었다.[11]

호어는 2009년경 모질라의 소규모 그룹이 프로젝트에 관심을 보이면서 이 언어에 대해 이야기하기 시작했다.[12] 그는 CLU(1974), BETA(1975), Mesa(1977), NIL(1981), Erlang(1987), 뉴스퀴크(Newsqueak) (1988), 네이피어(Napier88) (1988), 헤르메스(Hermes) (1990), Sather(1990), 알레프(Alef) (1992), 림보(1996)와 같은 언어들에서 영향을 받았다고 언급하며, "많은 오래된 언어가 새로운 언어보다 낫다"고 평가했다. 그리고 이 언어를 "과거의 기술이 미래를 구원하기 위해 온 것"이라고 묘사했다.[11][12] 초기 러스트 개발자 마니쉬 고레가오카(Manish Goregaokar) 역시 러스트가 "대부분 수십 년 된 연구"를 기반으로 한다고 설명했다.[10]

초창기 러스트의 컴파일러는 약 38,000줄의 OCaml로 작성되었다.[11][13] 초기에는 명시적인 객체 지향 프로그래밍 (나중에 제거됨)과, 변수의 상태 변경을 추적할 수 있는 타입 상태 시스템과 같은 기능을 포함했다. 함수는 기본적으로 순수 함수였으며, 명시적인 주석 없이는 부작용이 허용되지 않았다.[11]

모질라(Mozilla)는 2009년부터 Rust 개발에 관여하기 시작했으며[230][231], 2010년 모질라 서밋에서 처음 공개되었다[232]。초창기 Rust 컴파일러OCaml 언어로 만들어진 컴파일러(rustboot)가 사용되었지만[233], 2010년에는 Rust 언어 자체로 Rust 컴파일러를 만드는 셀프 호스팅으로 전환된 컴파일러(rustc) 개발이 시작되었고[234], 이듬해에는 부트스트랩 문제를 해결한 첫 번째 완성품이 완성되었다[235]。이때부터 Rust 컴파일러는 컴파일 기반으로 LLVM을 사용하게 되었다[236]

2. 2. 모질라 후원 (2009~2012)

모질라는 2009년에 러스트 프로젝트를 공식적으로 후원했다.[10] 브렌던 아이크를 비롯한 다른 임원들은 러스트를 안전한 웹 브라우저 엔진에 사용할 가능성에 주목하여, 패트릭 월튼, 니코 마차키스, 펠릭스 클록, 마니쉬 고레가오카를 포함한 엔지니어들을 프로젝트에 배치했다. 개발자들이 사용하던 회의실은 "너드 동굴"이라고 불렸으며, 문 밖에 표지판이 걸려 있었다.[10]

이 기간 동안, 초기 OCaml 컴파일러에서 LLVM 기반의 셀프 호스팅 컴파일러로 변경하는 작업이 진행되었다.[14] Rust 소유권 시스템도 2010년까지 구축되었다.[10] 2011년에는 자전거 체인링을 기반으로 한 러스트 로고가 개발되었다.[16]

첫 번째 공개 릴리스인 Rust 0.1은 2012년 1월에 출시되었다.[14] 2010년대 초반에는 모질라 외부 및 미국 외부의 오픈 소스 자원봉사자들의 참여가 증가했다. 모질라에서는 임원들이 향후 10년 동안 Rust에 전념할 12명 이상의 엔지니어를 고용하게 되었다.[10]

2. 3. 발전 (2012~2015)

러스트는 2012년부터 2015년까지 타입 시스템에 큰 변화를 겪었다. 타입 상태 시스템이 제거되고, 다른 언어 기능이 통합되었으며, 가비지 컬렉터가 제거되었다.[11][10] 소유권 시스템을 통한 메모리 관리가 점진적으로 확장되어 메모리 관련 버그를 방지했다. 2013년까지 가비지 컬렉터 기능은 거의 사용되지 않아 제거되었다.[10] 2013년 3월에는 명시적인 주석으로 선언되던 순수 함수가 제거되었다.[17] 언어 단순화를 위해 채널과 다양한 포인터 유형에 대한 특수 구문 지원이 제거되었다.[11]

객체 시스템은 러스트 0.2에서 0.4 버전에 걸쳐 많은 변화를 겪었다. 0.2 버전에서는 클래스가 도입되었고, 0.3 버전에서는 소멸자와 인터페이스가 도입되었다. 0.4 버전에서는 trait 기능이 도입되면서 인터페이스는 trait와 통합되었고, class는 제거되었다.[242]

0.4 버전 이전에는 정적 타입 검사와 더불어 타입 상태 분석 기능을 지원했다. 타입 상태 분석 기능은 선언문 전후에 `check` 키워드를 사용하여 해당 선언문이 의도대로 동작하는지 컴파일 시에 검사하는 기능이었으나, 실질적으로 거의 사용되지 않아 제거되었다.[240][241]

코어 메모리 모델은 0.9 버전부터 0.11 버전 사이에 단순화 과정을 거쳤다. 힙 메모리형 `~`과 가비지 컬렉션형 `@`의 두 가지 빌트인 포인터형은 표준 라이브러리의 `Box`형과 `Gc`형으로 대체되었고, `Gc`형은 최종적으로 삭제되었다.[242]

러스트의 발전은 C++ 개발자 (기능의 낮은 수준 성능), 스크립트 언어 (Cargo 및 패키지 관리), 함수형 프로그래밍 (타입 시스템 개발) 출신 개발자들의 영향을 받았다.[11]

판정은 0.4 버전 이전의 기존 정적 타이핑 외에, 형 상태 시스템을 지원했다. 형 상태 시스템은 특별한 check 문을 사용하여 프로그램 문 전후의 형 결정을 모델링했다. C 언어 및 C++ 코드에서의 어서션과 마찬가지로, 프로그램 실행 중이 아닌 컴파일 시에 형 불일치를 감지한다. 형 상태의 개념은 Rust 특유의 것이 아니라, NIL에서 채용되었던 것이다.[240]

2014년 1월, ''Dr. Dobb's Journal''의 편집장 앤드류 빈스톡(Andrew Binstock)은 러스트가 C++의 경쟁자가 될 가능성에 대해 D, Go, Nim과 함께 언급했다. 빈스톡에 따르면, 러스트는 "매우 우아한 언어로 널리 여겨졌지만", 버전마다 급격하게 변경되어 채택이 늦어졌다.[18][243]

그레이든 호어(Graydon Hoare)는 2013년에 러스트에서 물러났다.[10] 초기 6명으로 구성된 "코어 팀"은 의견 요청 (RFC) 프로세스를 통해 보다 연합된 거버넌스 구조하에서 발전했다.[11] 코어 팀은 2016년까지 9명으로 늘어났으며, 1600개 이상의 RFC가 제안되었다.[11]

모질라(Mozilla)가 개발을 후원한 지 6년 만인 2015년 5월 15일에 첫 번째 안정적 릴리스인 러스트 1.0이 공개되었다.[10] 릴리스 1년 후, 러스트 컴파일러는 1,400명 이상의 기여자를 확보했으며, 러스트 패키지 관리 웹사이트 Crates.io에 5,000개 이상의 타사 라이브러리가 게시되었다.[11]

2. 4. 안정화 (2015~2020)

Servo 브라우저 엔진의 개발은 러스트와 병행하여 진행되었으며, 모질라삼성의 공동 자금 지원을 받았다.[19] 두 프로젝트 팀은 긴밀하게 협력하여 러스트의 새로운 기능은 Servo 팀에서 테스트하고 Servo의 새로운 기능은 러스트 팀에 피드백하는 데 사용되었다.[11]

Servo의 첫 번째 버전은 2016년에 출시되었다.[10] 파이어폭스 웹 브라우저는 2016년(버전 45)부터 러스트 코드를 포함하여 출시되었지만,[11][20] Servo의 구성 요소는 2017년 9월(버전 57)에 Gecko 및 Quantum 프로젝트의 일부로 파이어폭스에 나타났다.[21]

1.0 이후 몇 년 동안 Rustfmt, 통합 개발 환경 통합, 정기적인 컴파일러 테스트 및 릴리스 주기, 커뮤니티 행동 강령, IRC 채팅을 통해 조직된 커뮤니티 토론을 포함하여 러스트 툴체인 생태계가 개선되었다.[11]

모질라 외부의 초기 채택은 삼성, 페이스북(현재 Meta Platforms), Dropbox 및 Tilde, Inc.(ember.js의 제작 회사)를 포함한 개별 프로젝트에서 이루어졌다.[11][10] 아마존 웹 서비스는 2020년에 뒤를 이었다.[10] 엔지니어들은 성능, 가비지 수집기 부재, 안전성 및 언어 작업의 즐거움을 채택 이유로 꼽았지만, 러스트가 새로운 기술이므로 위험한 선택임을 인정했다. 아마존 개발자들은 러스트가 포르투갈의 미뉴 대학교, 리스본 신대학교, 코임브라 대학교의 연구에서 밝혀진 바와 같이 자바로 작성된 유사한 코드보다 전력 소비가 절반밖에 되지 않으며 C 다음으로 효율적이라는 점을 언급했다.[10][22]

2015년 5월 16일, 안정 버전인 Rust 1.0이 출시되었다[244]。1.0 버전 이후, 안정 버전 및 베타 버전이 6주 간격으로 정기적으로 릴리스되고 있다[245]。또한 나이틀리 버전이 매일 릴리스되고 있다[246]。새로운 기능은 나이틀리 버전에서 개발이 진행되며, 베타 버전에서 동작이 검증되고 있다[247]

2016년 8월 2일에 릴리스된 Firefox 48에는 Rust로 다시 작성된 미디어 파서가 탑재되었으며, 모질라가 개발하고 있는 브라우저인 파이어폭스에서 Rust로 작성된 코드가 추가된 첫 번째 사례가 되었다[248][249]

2016년 9월에 Rust는 Fedora 24의 표준 구성 요소에 추가되었으며, RPM의 패키지 관리 시스템을 사용하여 설치 작업이 용이해졌다[250]

2. 5. 러스트 재단 설립 (2020~현재)

모질라 재단코로나19 범유행으로 인한 구조조정으로 2020년 8월에 서보 팀을 해체하면서, 러스트의 미래에 대한 우려가 제기되었다.[23][24][25] 이에 러스트 코어 팀은 러스트 재단 설립 계획을 발표하고, 모든 상표와 도메인 이름 소유권 및 재정적 책임을 재단으로 이전하는 것을 목표로 하였다.[26]

2021년 2월 8일, 아마존 웹 서비스, 구글, 화웨이, 마이크로소프트, 모질라 재단 등 5개 회사가 러스트 재단 설립을 공식 발표하였다.[27][28] 초대 의장은 셰인 밀러가 맡았으며, 재단은 주요 러스트 기능을 개발하는 프로그래머에게 재정적 지원을 제공했다.[10] 2021년 4월 6일, 구글은 안드로이드 오픈 소스 프로젝트 내에서 C/C++의 대안으로 러스트를 지원한다고 발표했다.[29]

2021년 11월 22일, 커뮤니티 행동 강령 시행을 담당하는 중재 팀은 코어 팀의 책임 문제를 제기하며 사임했다.[30] 2022년 5월, 러스트 코어 팀, 다른 수석 프로그래머 및 러스트 재단 이사회 일부 구성원은 이 사건에 대응하여 거버넌스 개혁을 시행했다.[31]

2023년 4월 6일, 러스트 재단은 러스트 로고와 이름 사용 규칙을 포함한 새로운 상표 정책 초안을 게시했으나, 사용자 및 기여자의 부정적인 반응을 얻었다.[32]

러스트 파운데이션(Rust Foundation)은 러스트 프로그래밍 언어와 생태계를 관리하는 독립적인 비영리 조직으로, "좋은 소프트웨어는 행복하고 잘 지원되는 사람들에 의해 만들어집니다"라는 모토를 갖고 프로젝트를 관리하고 개발하는 유지 관리자를 지원하는 데 중점을 두고 있다.[303]

3. 개발 체제

밝은 주황색 게 아이콘


러스트는 포용적인 커뮤니티를 갖춘 것으로 알려져 있으며, 특히 퀴어 커뮤니티의 사람들을 환영하는데, 이는 러스트 커뮤니티 구성원이 따라야 할 일련의 기대를 제시하는 행동 강령 때문이다. 한 MIT 테크놀로지 리뷰 기사는 러스트 커뮤니티를 초심자에게 "이례적으로 친절하다"고 묘사했다.[10][81]

러스트(Rust)는 오픈 소스 커뮤니티 기반으로 개발이 진행되고 있다. 프로젝트의 주관은 Rust Project Developers(러스트 개발 팀)이다.[146] 2018년 현재, 언어 발명자인 그레이든 호어는 프로젝트 팀에서 제외되었다. 프로젝트의 모든 소스 코드는 GitHub에 일반에 공개되어 있으며[147], 커뮤니티 멤버의 협력으로 개선이 이루어진다. 프로젝트의 대부분의 커밋은 커뮤니티 멤버에 의해 이루어진다.[148]

Mozilla의 이념[149]을 지키며, 러스트 언어는 사회에 개방되어 있으며, 언어 및 도구에 대한 사양 제안은 RFC 형태로 정리되고[150], 관련 티켓을 통해 사양 세부 사항에 대해 사용자로부터 소감 및 제안을 받고 있다.[151][152]

언어 및 코어 라이브러리를 개발하는 Rust 개발 팀은 Servo(웹 브라우저용 레이아웃 엔진) 및 Rust 컴파일러의 구현 경험을 통해 언어를 개선하고 있다. 예를 들어, C 언어와 러스트를 연동하는 코드를 자동 생성하는 bindgen은 원래 외부 개발자가 개발했지만[153], Mozilla Servo 개발 팀이 Servo 개발에 사용하기 위해 C++와 러스트를 연동하는 코드도 자동 생성할 수 있도록 개량을 거듭했으며, 현재는 Servo 개발 팀과 긴밀하게 협력하고 있는 Rust 개발 팀으로 주관을 이전하여[154] Servo 개발과 함께 개선이 계속되고 있다.[155]

러스트 프로젝트는 개발의 여러 하위 영역을 담당하는 ''팀''으로 구성되어 있다. 컴파일러 팀은 컴파일러 내부 구조를 개발, 관리 및 최적화하며, 언어 팀은 새로운 언어 기능을 설계하고 구현을 지원한다. 러스트 프로젝트 웹사이트에는 2024년 7월 기준으로 6개의 최상위 팀이 나열되어 있다.[135] 팀 대표들로 구성된 리더십 위원회는 러스트 프로젝트 전체를 감독한다.[136]

4. 설계 및 특징

러스트는 인터넷에서 실행되는 서버 및 클라이언트 프로그램을 개발하는데 적합한 언어를 목표로 설계되었다. 이 목표에 따라 러스트는 안전성과 병행 프로그래밍, 그리고 메모리 관리의 직접 제어에 초점을 맞추고 있다. 또한 성능 면에서는 C++와 비슷한 수준을 목표로 하고 있다. 미국 국토안보부에서도 이러한 점을 이유로 러스트, 고, C#의 안전한 언어로 전환을 권고했다.[290]

러스트의 문법은 중괄호로 코드 블록을 구분하고, `if`, `else`, `while` 등의 키워드를 사용하는 등 CC++와 유사한 모양을 하고 있다. 그러나 러스트와 C/C++는 의미상으로는 크게 다른 문법을 갖고 있다.

러스트는 메모리 오류를 발생시키지 않도록 설계되었다. 러스트는 널 포인터나 초기화되지 않은 포인터가 존재하지 않도록 강제하고 있다. 모든 변수는 초기값을 가지고 할당되며, 해제된 포인터에 접근하는 코드는 컴파일러가 미리 감지하여 컴파일 오류를 일으킨다.

타입 시스템은 하스켈의 영향을 받아 타입 클래스를 지원한다. 또한, 변수 선언 시 타입을 지정하지 않아도 컴파일러가 타입 추론을 통해 해당 변수의 타입을 지정할 수 있다. 반면 함수의 인자나 반환값에서는 타입 정보를 빼놓을 수 없다.

병행 프로그래밍은 얼랭과 유사한 actor 기반의 모델을 사용하고 있다. 각각의 태스크는 데이터를 직접 공유하지 않고 메시지 전달을 통해서만 데이터를 교환할 수 있다. 메시지를 복사할 때 생기는 성능 저하를 막기 위해, unique box의 경우 데이터 복사 없이 메시지를 전달할 수 있다. unique box는 하나의 객체만이 소유할 수 있고, 다른 태스크로 전달될 경우 데이터 복사 없이 소유권만 바뀌게 된다.

객체 시스템은 implementation, trait, struct 또는 enum으로 이루어져 있다. `struct` 또는 `enum`은 객체의 데이터를 정의하는데 사용되며, `impl` 키워드로 정의하는 implementation은 객체의 멤버 함수를 정의하는데 사용된다. 객체의 상속은 `trait`을 통해 이루어지며, C++의 다형 상속 문제를 회피하기 위해 trait은 객체의 멤버를 정의할 수 없도록 만들어져 있다.

linux.conf.au에서 공개된 Rust 프로그래밍의 성공적인 수행에 필요한 주요 개념을 소개하는 프레젠테이션


러스트의 문법은 C와 C++와 유사하지만,[33][131] 많은 기능은 함수형 프로그래밍 언어, 예를 들어 OCaml의 영향을 받았다. 호어(Hoare)는 러스트가 좌절한 C++ 개발자를 대상으로 하며, 안전성, 메모리 레이아웃 제어, 동시성과 같은 기능을 강조했다고 설명했다.[12] 러스트의 안전성은 메모리 안전성, 타입 안전성 및 데이터 경합의 부재를 보장한다.

== 패러다임 ==

러스트는 프로그래밍 패러다임이 특정 구현 방식에 한정되지 않는 비순수한 멀티 패러다임 프로그래밍 언어이다. 문법의 표면적인 기술은 절차적 프로그래밍, 블록 코드 묶음의 의미론은 함수형 프로그래밍의 특성을 가지며, 타입 시스템을 사용한 객체 구조는 객체 지향 프로그래밍의 패러다임 특성을 가진다. 특정 프로그래밍 패러다임만을 사용하여 소스 코드를 작성하는 것이 아니라, 요점마다 필요한 곳에 필요한 패러다임을 사용하여 소스 코드를 작성하게 된다.

소스 코드를 타겟 플랫폼에 최적화된 오브젝트 파일로 컴파일하는 컴파일 언어의 패러다임 특성을 가진다. 많은 스크립트 언어가 가지는 인터프리터 기능이나, Swift나 Go가 제공하는 REPL 기능과 같은 패러다임 특성은 가지지 않는다.

그 외의 패러다임으로, 함수의 입출력 파라미터에 제네릭 타입을 지정하는 제네릭 프로그래밍, 비동기 기능을 실현하는 병렬 컴퓨팅의 패러다임 특성을 가진다.

== 기초 문법 ==

러스트의 문법은 C와 C++와 유사하지만,[33][131] 많은 기능은 함수형 프로그래밍 언어, 예를 들어 OCaml의 영향을 받았다.

러스트에서, 코드 블록은 중괄호로 구분된다.

`if` 조건식은 주어진 값이 `true`인지 여부에 따라 코드를 실행한다. `else`는 값이 `false`로 평가될 때 사용될 수 있으며, `else if`는 여러 식을 결합하는 데 사용될 수 있다.

```rust

fn main() {

let x = 10;

if x > 5 {

println!("value is greater than five");

}

if x % 7 == 0 {

println!("value is divisible by 7");

} else if x % 5 == 0 {

println!("value is divisible by 5");

} else {

println!("value is not divisible by 7 or 5");

}

}

```

`while`는 조건이 충족되는 동안 코드 블록을 반복하는 데 사용할 수 있다.

```rust

fn main() {

// 4부터 10까지의 모든 정수를 반복한다.

let mut value = 4;

while value <= 10 {

println!("value = {value}");

value += 1

}

}

```

러스트의 for 루프는 컬렉션의 요소를 반복한다.

"for" 표현식은 모든 반복자 유형에 대해 작동한다.

```rust

fn main() {

// 위와 동일한 기능을 위해 범위 구문을 사용하여 `for` 사용

for value in 4..=10 {

println!("value = {value}");

}

}

```

위 코드에서 `4..=10`은 `Iterator` 트레이트를 구현하는 `Range` 유형의 값이다. 중괄호 안의 코드는 반복자가 반환하는 각 요소에 적용된다.

반복자는 `map`, `filter` 및 `sum`과 같은 반복자 함수와 결합될 수 있다. 예를 들어, 다음은 3의 배수인 1과 100 사이의 모든 숫자를 더한다.

```rust

(1..=100).filter(|&x| x % 3 == 0).sum()

```

일반적으로 `loop` 키워드를 사용하면 `break`가 발생할 때까지 코드의 일부를 반복할 수 있다. `break`는 선택적으로 값을 가지고 루프를 종료할 수 있다. 루프가 중첩된 경우, `'label_name`으로 표시된 레이블을 사용하여 외부 루프를 중단할 수 있다.

```rust

fn main() {

let value = 456;

let mut x = 1;

let y = loop {

x *= 10;

if x > value {

break x / 10;

}

};

println!("value보다 작거나 같은 가장 큰 10의 거듭제곱: {y}");

let mut up = 1;

'outer: loop {

let mut down = 120;

loop {

if up > 100 {

break 'outer;

}

if down < 4 {

break;

}

down /= 2;

up += 1;

println!("up: {up}, down: {down}");

}

up *= 2;

}

}

```

러스트는 표현식 지향 프로그래밍 언어이며, 함수 본문의 거의 모든 부분이 표현식이며, 제어 흐름 연산자도 포함된다. `if` 표현식은 삼항 조건 연산자를 제공하는 데 사용된다. 반환이 암시적이므로 함수는 `return` 표현식으로 끝낼 필요가 없다. 세미콜론이 생략되면 함수에서 마지막 표현식의 값이 반환 값으로 사용된다.[34]

블록 코드 내의 명령문의 구분 기호로는 세미콜론(`;`)을 사용하지만, C의 그것과 달리 Rust의 세미콜론은 바로 앞의 명령문이 블록 코드로 묶이는 식의 중간 식임을 선언하기 위한 것이다. 세미콜론을 말미에 두지 않은 명령문은 블록 코드의 최종적인 평가식으로 취급되며, 그 식의 결과가 블록 코드 밖으로 반환값으로 반환된다[157].

다음의 재귀 팩토리얼 함수 구현에서 볼 수 있다.

```rust

fn factorial(i: u64) -> u64 {

if i == 0 {

1

} else {

i * factorial(i - 1)

}

}

```

다음의 반복 구현은 `..=` 연산자를 사용하여 포괄적인 범위를 만든다.

```rust

fn factorial(i: u64) -> u64 {

(2..=i).product()

}

```

러스트의 `match` 표현식과 `if let` 표현식은 패턴 매칭에 사용될 수 있다. 예를 들어, `match`는 선택적 정수 값이 있는 경우 두 배로 만들고, 그렇지 않은 경우 0을 반환하는 데 사용할 수 있다.

```rust

fn double(x: Option) -> u64 {

match x {

Some(x) => x * 2,

None => 0,

}

}

```

이것은 `if let`과 `else`로 동일하게 작성할 수 있다.

```rust

fn double(x: Option) -> u64 {

if let Some(x) = x {

x * 2

} else {

0

}

}

```

Rust의 기본적인 문법은 C 언어나 C++(C++)와 유사하며, 중괄호로 묶인 블록 코드 `{ ... }`, `if`, `else`, `while` 등의 제어 흐름 키워드를 가지고 있다.

모든 C 언어나 C++의 키워드가 구현되어 있는 것은 아니며, 한편 몇몇 Rust의 제어 명령(예를 들어 패턴 매칭을 위한 `match`)은 해당 언어를 습득한 프로그래머에게는 익숙하지 않은 것도 존재한다. Rust의 명령문은 표면적인 C 언어나 C++와의 문법적 유사성에도 불구하고, 의미론적으로는 ML 계열 언어의 명령식에 가까우며, 함수 본체의 거의 모든 부분은 제어 흐름 연산자조차도 "문(statement)"이 아니라 "식(expression)"이다[156]. 예를 들어 일반적인 `if` 식도 C 언어에서 말하는 조건 연산자이며, `if` 식의 결과로 반환값을 반환한다.

== Hello World ==

아래 코드는 러스트 1.0 기준이며, 러스트의 문법은 향후 변경될 수 있다.

"Hello, world!"를 표준 출력에 출력하는 헬로 월드 프로그램은 다음과 같다.

```rust

fn main() {

println!("Hello, world!");

}

```

`fn` 키워드는 함수를 나타내며, `println!` 매크로는 메시지를 표준 출력으로 출력한다. 러스트의 세미콜론으로 구분된다.

== 계승 ==

아래는 각각 재귀함수와 반복문을 사용해 작성된 계승 함수이다:

```rust

/* 이 함수는 러스트의 암묵적 반환문을 이용해 작성되었다. C 스타일 언어들과 달리

러스트의 `if` 문은 선언문이 아닌 표현식이므로, `if` 문에도 반환값이 존재한다. */

fn recursive_factorial(n: isize) -> isize {

if n <= 1 { 1 }

else { n * recursive_factorial(n-1) }

}

fn iterative_factorial(n: isize) -> isize {

// `mut` 키워드는 값이 바뀔 수 있는 변수를 가리킨다.

let mut i = 1;

let mut result = 1;

while i <= n {

result *= i;

i += 1

}

return result; // 위의 예제와 달리 명시적 반환문을 사용한다

}

fn foreach_factorial(n: isize) -> isize {

// 1.21 버전부터는 for_each가 가능해졌다.

let mut result = 1;

(1..n+1).for_each(|i| result *= i);

return result;

}

```

계승을 구하는 프로그램. `if`식의 결과로 `1` 또는 `n * fac_recursive(n-1)`을 반환하고, 함수의 결과로 `if`식의 결과를 반환한다.

```rust

fn fac_recursive(n: u32) -> u32 {

if n <= 1 {

1

} else {

n * fac_recursive(n-1)

}

}

```

== 변수 ==

변수는 러스트에서 `let` 키워드를 통해 정의된다. 변수는 기본적으로 불변이며, 재할당 시 컴파일 오류가 발생한다.

```rust

fn main() {

let foo = 10;

println!("foo의 값은 {foo}입니다");

}

```

`mut` 키워드를 추가하면 변수를 변경할 수 있다. 이는 예를 들어 큰 구조체의 복사를 피하면서 일부를 변경하는 데 유용하다.

```rust

fn main() {

let mut foo = 10; // "mut"를 추가하지 않으면 이 코드는 컴파일되지 않습니다.

println!("foo의 값은 {foo}입니다");

foo = 20;

println!("foo의 값은 {foo}입니다");

}

```

여러 개의 `let` 표현식을 사용하여 변수 섀도잉으로 알려진, 동일한 이름을 가진 여러 변수를 정의할 수 있다. 섀도잉을 사용하면 변수의 이름을 다르게 지정하지 않고도 변수를 변환할 수 있으며, 일시적인 변수 변경 및 변수 타입 변경이 가능하다.

```rust

fn main() {

let foo = 10;

println!("foo의 값은 {foo}입니다");

let foo = foo * 2;

println!("foo의 값은 {foo}입니다");

}

```

```rust

fn main() {

let spaces = " ";

let spaces = spaces.len();

}

```

변수와 별개로 `const` 키워드로 정의되는 상수가 있다. 상수는 항상 동일한 값을 가지며 `mut` 및 섀도잉을 지원하지 않는다.

== 타입과 다형성 ==

러스트(프로그래밍 언어)가 갖춘 형식 시스템은 `impl`(구현), trait(트레이트), struct(구조체) 및 enum(열거형)을 기본으로 구성된다. `impl`이 다른 언어의 클래스와 비슷한 역할을 하며, 상속과 다형성은 트레이트를 통해 제공된다. 트레이트에는 메서드를 정의할 수 있으며, 트레이트에서 선언된 메서드는 `impl`에 의해 struct에 믹스인된다. struct에는 필드를 정의할 수 있으며, 트레이트와 `impl` 자체에는 필드를 정의할 수 없다. enum에는 여러 종류의 형식 범주 변수를 정의할 수 있으며, 수치형, 문자열형, 객체형 등 여러 상태를 선택적으로 가질 수 있다. 다이아몬드 상속 문제를 회피하기 위해 트레이트만 상속이 가능하다.

사용자 정의 타입은 `struct` 또는 `enum` 키워드를 사용하여 생성된다. `struct` 키워드는 여러 관련 값을 그룹화하는 레코드 타입을 나타내는 데 사용된다. `enum`은 런타임에 서로 다른 변형을 가질 수 있으며, 기능은 함수형 프로그래밍 언어에서 발견되는 대수적 데이터 타입과 유사하다. struct와 enum 모두 서로 다른 타입을 가진 필드를 포함할 수 있다. 동일한 타입에 대한 다른 이름은 `type` 키워드를 사용하여 정의할 수 있다.

`impl` 키워드는 사용자 정의 타입에 대한 메서드를 정의할 수 있다. 데이터와 함수는 별도로 정의된다. 구현은 다른 언어의 클래스와 유사한 역할을 수행한다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

이 언어의 타입 시스템은 Haskell 언어를 따라 "타입 클래스"를 사용할 수 있다. 이는 애드혹한 다형성을 쉽게 구현하며, 가변형 선언으로 실현된다. 고차 카인드 다형성[163] 등, Haskell 언어에 있는 다른 특징은 지원되지 않는다.

=== 타입 추론 ===

러스트 컴파일러는 변수에 대입할 때(`variable = value`), 변수의 형을 값의 형에 기초하여 형 추론한다. 변수의 선언에는 반드시 형을 결정하기 위한 초기값을 필요로 하지 않는다. 변수의 선언 시 초기값이 주어진 경우에는 "변수의 형"은 "초기값의 형"이라고 형 추론이 이루어지지만, 초기값이 주어지지 않은 경우에는 이후 블록 코드 중 그 변수에 값이 처음 대입되었을 때 "좌변의 변수의 형"은 "우변의 대입하는 값의 형"이라고 형 추론이 이루어진다. 변수에의 대입이 형 불일치에 의해 실패한 경우에는 컴파일 시에 에러를 검출한다[165].

=== 다형성 실현 ===

러스트의 더 발전된 기능에는 제네릭 함수의 사용이 포함된다. 제네릭 함수는 제네릭 매개변수를 받아서 동일한 함수를 서로 다른 변수 유형에 적용할 수 있도록 한다. 이 기능은 중복 코드를 줄여주며 매개변수 다형성으로 알려져 있다.

다음 프로그램은 두 개의 값을 더하는 함수로, 덧셈 연산이 제네릭 함수를 사용하여 구현된다.

```rust

use std::ops::Add;

// sum은 T라는 한 개의 타입 매개변수를 갖는 제네릭 함수이다.

fn sum(num1: T, num2: T) -> T

where

T: Add, // T는 덧셈이 또 다른 T를 반환하는 Add 트레이트를 구현해야 한다.

{

num1 + num2 // num1 + num2는 Add 트레이트에 의해 제공되는 num1.add(num2)의 구문 설탕이다.

}

fn main() {

let result1 = sum(10, 20);

println!("Sum is: {}", result1); // Sum is: 30

let result2 = sum(10.23, 20.45);

println!("Sum is: {}", result2); // Sum is: 30.68

}

```

컴파일 시점에, `sum`과 같은 다형성 함수는 코드에서 필요로 하는 특정 타입으로 인스턴스화된다. 이 경우 정수의 합과 부동 소수점의 합이다.

제네릭은 동일한 코드를 반복하지 않고도 서로 다른 타입에 대한 동작을 구현할 수 있도록 하기 위해 함수에서 사용될 수 있다. 제네릭 함수는 실제 타입을 알지 못한 채, 다른 제네릭과 관련하여 작성될 수 있다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

러스트의 트레이트는 정적 디스패치를 사용하여 구현된다. 이는 모든 값의 형식이 컴파일 시간에 알려진다는 것을 의미한다. 그러나 러스트는 또한 ''트레이트 객체''라고 하는 기능을 사용하여 동적 디스패치를 수행한다. 이는 다형적 연산의 구현이 런타임에 선택되는 다형성의 한 유형이다. 이를 통해 주어진 트레이트를 구현하는 모든 데이터 형식을 기능적으로 동일하게 취급할 수 있는 덕 타이핑과 유사한 동작을 허용한다.[59] 트레이트 객체는 `dyn Tr` 구문을 사용하여 선언되며, 여기서 `Tr`은 트레이트이다. 트레이트 객체는 동적으로 크기가 조정되므로 `Box`와 같은 포인터 뒤에 두어야 한다. 다음 예제는 각 객체를 `Display` 트레이트를 사용하여 출력할 수 있는 객체 목록을 만듭니다.

```rust

use std::fmt::Display;

let v: Vec> = vec![

Box::new(3),

Box::new(5.0),

Box::new("hi"),

];

for x in v {

println!("{x}");

}

```

목록의 요소가 `Display` 트레이트를 구현하지 않으면 컴파일 시간 오류가 발생한다.

구조체의 필드 및 함수의 입출력 값은 특정 트레이트를 구현하는 제네릭 타입을 지정하여 다형성을 실현할 수 있다. 이러한 정의 내에서 제네릭 타입으로 타입이 선언된 변수 및 입출력 값은 해당 트레이트의 특성만 사용할 수 있다. 이는 제네릭 함수가 정의되면 즉시 타입 판별이 가능하다는 것을 의미한다. 이는 C++덕 타이핑에서 구체적인 타입이 인스턴스화될 때까지 판별할 수 없는 템플릿과는 대조적이다. 그러나 Rust의 제네릭 구현은 C++의 템플릿의 전형적인 구현과 유사하며, 인스턴스화될 때마다 코드의 개별 복사본이 생성된다. 이는 단상화[166]라고 불리며, Java나 Haskell에서 일반적으로 사용되는 타입 소거 방식과는 대조적이다. 단상화의 장점은 특정 사용 사례에 최적화된 코드이며, 단점은 결과 바이너리의 컴파일 시간 및 크기가 증가한다는 것이다. Rust의 트레이트를 사용한 다형성 실현은 런타임 오버헤드가 없는 "제로 코스트 추상화"로 표현된다[167].

== 타입 시스템 ==

러스트(프로그래밍 언어)가 갖춘 형식 시스템은 `impl`(구현), trait(트레이트), struct(구조체) 및 enum(열거형)을 기본으로 구성된다. `impl`이 다른 언어의 클래스와 비슷한 역할을 하며, 상속과 다형성은 트레이트를 통해 제공된다. 트레이트에는 메서드를 정의할 수 있으며, 트레이트에서 선언된 메서드는 `impl`에 의해 struct에 믹스인된다. struct에는 필드를 정의할 수 있으며, 트레이트와 `impl` 자체에는 필드를 정의할 수 없다. enum에는 여러 종류의 형식 범주 변수를 정의할 수 있으며, 수치형, 문자열형, 객체형 등 여러 상태를 선택적으로 가질 수 있다. 다이아몬드 상속 문제를 회피하기 위해 트레이트만 상속이 가능하다.

사용자 정의 타입은 `struct` 또는 `enum` 키워드를 사용하여 생성된다. `struct` 키워드는 여러 관련 값을 그룹화하는 레코드 타입을 나타내는 데 사용된다. `enum`은 런타임에 서로 다른 변형을 가질 수 있으며, 기능은 함수형 프로그래밍 언어에서 발견되는 대수적 데이터 타입과 유사하다. struct와 enum 모두 서로 다른 타입을 가진 필드를 포함할 수 있다. 동일한 타입에 대한 다른 이름은 `type` 키워드를 사용하여 정의할 수 있다.

`impl` 키워드는 사용자 정의 타입에 대한 메서드를 정의할 수 있다. 데이터와 함수는 별도로 정의된다. 구현은 다른 언어의 클래스와 유사한 역할을 수행한다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

변수의 형식을 결정하는 형식 시스템은 정적 타입이며 강력한 타입이다. 정적 타입과 동적 타입의 구분에서 형식은 컴파일 시 모든 변수에 대해 형식을 결정하는 정적 타입을 기본으로 하지만, 트레이트를 포인터를 통해 사용하여 덕 타이핑과 유사한 형식 지정을 할 수 있는 트레이트 객체가 존재한다. 또한, Any 트레이트를 사용하여 런타임 리플렉션을 사용한 동적 타입 지정도 가능하다. 강력한 타입과 약한 타입의 구분에서 형식 지정은 실행 시 변수의 형식을 형 변환 (업캐스팅, 다운캐스팅, 크로스 캐스팅) 및 박싱을 허용하지 않는 강력한 타입 지정을 지원한다. C 언어, 자바는 실행 시 형 변환을 허용하는 약한 타입 지정을 지원하지만, 러스트 언어에서는 변환 대상 형식이 명시되지 않은 상황에서의 형 변환은 인정되지 않는다. 또한, 형식이 확정된 변수에의 대입이나, 시그니처에 의해 형식이 확정된 함수에의 인수 전달 및 반환값 수신 등에서는, 형식 강제를 위한 함수가 정의되어 있으면 이를 암묵적으로 호출할 수 있다.[164]

== 리소스 관리 ==

시스템 프로그래밍 언어에는 효율적인 리소스 관리 기능이 필수적이다 (예: 메모리·파일 관리). C 언어는 프로그래머가 리소스를 직접 관리하여 높은 효율을 얻을 수 있지만, 메모리 누수와 같은 버그가 발생할 위험을 내포하고 있다. 보다 고급 언어(예: Java)에서는 가비지 컬렉션과 같은 동적 리소스 관리 기구로 높은 안전성을 확보할 수 있지만, 동적 관리의 오버헤드가 항상 따른다.

Rust는 소유권을 중심으로 RAII·

4. 1. 패러다임

러스트는 프로그래밍 패러다임이 특정 구현 방식에 한정되지 않는 비순수한 멀티 패러다임 프로그래밍 언어이다. 문법의 표면적인 기술은 절차적 프로그래밍, 블록 코드 묶음의 의미론은 함수형 프로그래밍의 특성을 가지며, 타입 시스템을 사용한 객체 구조는 객체 지향 프로그래밍의 패러다임 특성을 가진다. 특정 프로그래밍 패러다임만을 사용하여 소스 코드를 작성하는 것이 아니라, 요점마다 필요한 곳에 필요한 패러다임을 사용하여 소스 코드를 작성하게 된다.

소스 코드를 타겟 플랫폼에 최적화된 오브젝트 파일로 컴파일하는 컴파일 언어의 패러다임 특성을 가진다. 많은 스크립트 언어가 가지는 인터프리터 기능이나, Swift나 Go가 제공하는 REPL 기능과 같은 패러다임 특성은 가지지 않는다.

그 외의 패러다임으로, 함수의 입출력 파라미터에 제네릭 타입을 지정하는 제네릭 프로그래밍, 비동기 기능을 실현하는 병렬 컴퓨팅의 패러다임 특성을 가진다.

4. 2. 기초 문법

러스트의 문법은 C와 C++와 유사하지만,[33][131] 많은 기능은 함수형 프로그래밍 언어, 예를 들어 OCaml의 영향을 받았다.

러스트에서, 코드 블록은 중괄호로 구분된다.

조건식은 주어진 값이 인지 여부에 따라 코드를 실행한다. 는 값이 로 평가될 때 사용될 수 있으며, 는 여러 식을 결합하는 데 사용될 수 있다.

```rust

fn main() {

let x = 10;

if x > 5 {

println!("value is greater than five");

}

if x % 7 == 0 {

println!("value is divisible by 7");

} else if x % 5 == 0 {

println!("value is divisible by 5");

} else {

println!("value is not divisible by 7 or 5");

}

}

```

while는 조건이 충족되는 동안 코드 블록을 반복하는 데 사용할 수 있다.

```rust

fn main() {

// 4부터 10까지의 모든 정수를 반복한다.

let mut value = 4;

while value <= 10 {

println!("value = {value}");

value += 1

}

}

```

러스트의 for 루프는 컬렉션의 요소를 반복한다.

"for" 표현식은 모든 반복자 유형에 대해 작동한다.

```rust

fn main() {

// 위와 동일한 기능을 위해 범위 구문을 사용하여 `for` 사용

for value in 4..=10 {

println!("value = {value}");

}

}

```

위 코드에서 `4..=10`은 `Iterator` 트레이트를 구현하는 `Range` 유형의 값이다. 중괄호 안의 코드는 반복자가 반환하는 각 요소에 적용된다.

반복자는 `map`, `filter` 및 `sum`과 같은 반복자 함수와 결합될 수 있다. 예를 들어, 다음은 3의 배수인 1과 100 사이의 모든 숫자를 더한다.

```rust

(1..=100).filter(|&x| x % 3 == 0).sum()

```

일반적으로 키워드를 사용하면 가 발생할 때까지 코드의 일부를 반복할 수 있다. 는 선택적으로 값을 가지고 루프를 종료할 수 있다. 루프가 중첩된 경우, 으로 표시된 레이블을 사용하여 외부 루프를 중단할 수 있다.

```rust

fn main() {

let value = 456;

let mut x = 1;

let y = loop {

x *= 10;

if x > value {

break x / 10;

}

};

println!("value보다 작거나 같은 가장 큰 10의 거듭제곱: {y}");

let mut up = 1;

'outer: loop {

let mut down = 120;

loop {

if up > 100 {

break 'outer;

}

if down < 4 {

break;

}

down /= 2;

up += 1;

println!("up: {up}, down: {down}");

}

up *= 2;

}

}

```

러스트는 표현식 지향 프로그래밍 언어이며, 함수 본문의 거의 모든 부분이 표현식이며, 제어 흐름 연산자도 포함된다. `if` 표현식은 삼항 조건 연산자를 제공하는 데 사용된다. 반환이 암시적이므로 함수는 `return` 표현식으로 끝낼 필요가 없다. 세미콜론이 생략되면 함수에서 마지막 표현식의 값이 반환 값으로 사용된다.[34]

블록 코드 내의 명령문의 구분 기호로는 세미콜론(`;`)을 사용하지만, C의 그것과 달리 Rust의 세미콜론은 바로 앞의 명령문이 블록 코드로 묶이는 식의 중간 식임을 선언하기 위한 것이다. 세미콜론을 말미에 두지 않은 명령문은 블록 코드의 최종적인 평가식으로 취급되며, 그 식의 결과가 블록 코드 밖으로 반환값으로 반환된다[157].

다음의 재귀 팩토리얼 함수 구현에서 볼 수 있다.

```rust

fn factorial(i: u64) -> u64 {

if i == 0 {

1

} else {

i * factorial(i - 1)

}

}

```

다음의 반복 구현은 `..=` 연산자를 사용하여 포괄적인 범위를 만든다.

```rust

fn factorial(i: u64) -> u64 {

(2..=i).product()

}

```

러스트의 표현식과 표현식은 패턴 매칭에 사용될 수 있다. 예를 들어, 는 선택적 정수 값이 있는 경우 두 배로 만들고, 그렇지 않은 경우 0을 반환하는 데 사용할 수 있다.

```rust

fn double(x: Option) -> u64 {

match x {

Some(x) => x * 2,

None => 0,

}

}

```

이것은 과 로 동일하게 작성할 수 있다.

```rust

fn double(x: Option) -> u64 {

if let Some(x) = x {

x * 2

} else {

0

}

}

```

Rust의 기본적인 문법은 C 언어나 C++(C++)와 유사하며, 중괄호로 묶인 블록 코드 { ... }, if, else, while 등의 제어 흐름 키워드를 가지고 있다.

모든 C 언어나 C++의 키워드가 구현되어 있는 것은 아니며, 한편 몇몇 Rust의 제어 명령(예를 들어 패턴 매칭을 위한 match)은 해당 언어를 습득한 프로그래머에게는 익숙하지 않은 것도 존재한다. Rust의 명령문은 표면적인 C 언어나 C++와의 문법적 유사성에도 불구하고, 의미론적으로는 ML 계열 언어의 명령식에 가까우며, 함수 본체의 거의 모든 부분은 제어 흐름 연산자조차도 "문(statement)"이 아니라 "식(expression)"이다[156]. 예를 들어 일반적인 if 식도 C 언어에서 말하는 조건 연산자이며, if 식의 결과로 반환값을 반환한다.

4. 2. 1. Hello World

아래 코드는 러스트 1.0 기준이며, 러스트의 문법은 향후 변경될 수 있다.

"Hello, world!"를 표준 출력에 출력하는 헬로 월드 프로그램은 다음과 같다.

```rust

fn main() {

println!("Hello, world!");

}

```

`fn` 키워드는 함수를 나타내며, `println!` 매크로는 메시지를 표준 출력으로 출력한다. 러스트의 세미콜론으로 구분된다.

4. 2. 2. 계승

아래는 각각 재귀함수와 반복문을 사용해 작성된 계승 함수이다:



/* 이 함수는 러스트의 암묵적 반환문을 이용해 작성되었다. C 스타일 언어들과 달리

러스트의 `if` 문은 선언문이 아닌 표현식이므로, `if` 문에도 반환값이 존재한다. */

fn recursive_factorial(n: isize) -> isize {

if n <= 1 { 1 }

else { n * recursive_factorial(n-1) }

}

fn iterative_factorial(n: isize) -> isize {

// `mut` 키워드는 값이 바뀔 수 있는 변수를 가리킨다.

let mut i = 1;

let mut result = 1;

while i <= n {

result *= i;

i += 1;

}

return result; // 위의 예제와 달리 명시적 반환문을 사용한다

}

fn foreach_factorial(n: isize) -> isize {

// 1.21 버전부터는 for_each가 가능해졌다.

let mut result = 1;

(1..n+1).for_each(|i| result *= i);

return result;

}



계승을 구하는 프로그램. if식의 결과로 1 또는 n * fac_recursive(n-1)을 반환하고, 함수의 결과로 if식의 결과를 반환한다.



fn fac_recursive(n: u32) -> u32 {

if n <= 1 {

1

} else {

n * fac_recursive(n-1)

}

}


4. 3. 변수

변수는 러스트에서 `let` 키워드를 통해 정의된다. 변수는 기본적으로 불변이며, 재할당 시 컴파일 오류가 발생한다.

```rust

fn main() {

let foo = 10;

println!("foo의 값은 {foo}입니다");

}

```

`mut` 키워드를 추가하면 변수를 변경할 수 있다. 이는 예를 들어 큰 구조체의 복사를 피하면서 일부를 변경하는 데 유용하다.

```rust

fn main() {

let mut foo = 10; // "mut"를 추가하지 않으면 이 코드는 컴파일되지 않습니다.

println!("foo의 값은 {foo}입니다");

foo = 20;

println!("foo의 값은 {foo}입니다");

}

```

여러 개의 `let` 표현식을 사용하여 변수 섀도잉으로 알려진, 동일한 이름을 가진 여러 변수를 정의할 수 있다. 섀도잉을 사용하면 변수의 이름을 다르게 지정하지 않고도 변수를 변환할 수 있으며, 일시적인 변수 변경 및 변수 타입 변경이 가능하다.

```rust

fn main() {

let foo = 10;

println!("foo의 값은 {foo}입니다");

let foo = foo * 2;

println!("foo의 값은 {foo}입니다");

}

```

```rust

fn main() {

let spaces = " ";

let spaces = spaces.len();

}

```

변수와 별개로 `const` 키워드로 정의되는 상수가 있다. 상수는 항상 동일한 값을 가지며 `mut` 및 섀도잉을 지원하지 않는다.

4. 4. 타입과 다형성

러스트(프로그래밍 언어)가 갖춘 형식 시스템은 `impl`(구현), trait(트레이트), struct(구조체) 및 enum(열거형)을 기본으로 구성된다. `impl`이 다른 언어의 클래스와 비슷한 역할을 하며, 상속과 다형성은 트레이트를 통해 제공된다. 트레이트에는 메서드를 정의할 수 있으며, 트레이트에서 선언된 메서드는 `impl`에 의해 struct에 믹스인된다. struct에는 필드를 정의할 수 있으며, 트레이트와 `impl` 자체에는 필드를 정의할 수 없다. enum에는 여러 종류의 형식 범주 변수를 정의할 수 있으며, 수치형, 문자열형, 객체형 등 여러 상태를 선택적으로 가질 수 있다. 다이아몬드 상속 문제를 회피하기 위해 트레이트만 상속이 가능하다.

사용자 정의 타입은 `struct` 또는 `enum` 키워드를 사용하여 생성된다. `struct` 키워드는 여러 관련 값을 그룹화하는 레코드 타입을 나타내는 데 사용된다. `enum`은 런타임에 서로 다른 변형을 가질 수 있으며, 기능은 함수형 프로그래밍 언어에서 발견되는 대수적 데이터 타입과 유사하다. struct와 enum 모두 서로 다른 타입을 가진 필드를 포함할 수 있다. 동일한 타입에 대한 다른 이름은 `type` 키워드를 사용하여 정의할 수 있다.

`impl` 키워드는 사용자 정의 타입에 대한 메서드를 정의할 수 있다. 데이터와 함수는 별도로 정의된다. 구현은 다른 언어의 클래스와 유사한 역할을 수행한다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

이 언어의 타입 시스템은 Haskell 언어를 따라 "타입 클래스"를 사용할 수 있다. 이는 애드혹한 다형성을 쉽게 구현하며, 가변형 선언으로 실현된다. 고차 카인드 다형성[163] 등, Haskell 언어에 있는 다른 특징은 지원되지 않는다.

=== 타입 추론 ===

러스트 컴파일러는 변수에 대입할 때(variable = value), 변수의 형을 값의 형에 기초하여 형 추론한다. 변수의 선언에는 반드시 형을 결정하기 위한 초기값을 필요로 하지 않는다. 변수의 선언 시 초기값이 주어진 경우에는 "변수의 형"은 "초기값의 형"이라고 형 추론이 이루어지지만, 초기값이 주어지지 않은 경우에는 이후 블록 코드 중 그 변수에 값이 처음 대입되었을 때 "좌변의 변수의 형"은 "우변의 대입하는 값의 형"이라고 형 추론이 이루어진다. 변수에의 대입이 형 불일치에 의해 실패한 경우에는 컴파일 시에 에러를 검출한다[165].

=== 다형성 실현 ===

러스트의 더 발전된 기능에는 제네릭 함수의 사용이 포함된다. 제네릭 함수는 제네릭 매개변수를 받아서 동일한 함수를 서로 다른 변수 유형에 적용할 수 있도록 한다. 이 기능은 중복 코드를 줄여주며 매개변수 다형성으로 알려져 있다.

구조체의 필드 및 함수의 입출력 값은 특정 트레이트를 구현하는 제네릭 타입을 지정하여 다형성을 실현할 수 있다. 이러한 정의 내에서 제네릭 타입으로 타입이 선언된 변수 및 입출력 값은 해당 트레이트의 특성만 사용할 수 있다. 이는 제네릭 함수가 정의되면 즉시 타입 판별이 가능하다는 것을 의미한다. 이는 C++덕 타이핑에서 구체적인 타입이 인스턴스화될 때까지 판별할 수 없는 템플릿과는 대조적이다. 그러나 Rust의 제네릭 구현은 C++의 템플릿의 전형적인 구현과 유사하며, 인스턴스화될 때마다 코드의 개별 복사본이 생성된다. 이는 단상화[166]라고 불리며, Java나 Haskell에서 일반적으로 사용되는 타입 소거 방식과는 대조적이다. 단상화의 장점은 특정 사용 사례에 최적화된 코드이며, 단점은 결과 바이너리의 컴파일 시간 및 크기가 증가한다는 것이다. Rust의 트레이트를 사용한 다형성 실현은 런타임 오버헤드가 없는 "제로 코스트 추상화"로 표현된다[167].

4. 4. 1. 타입 시스템

러스트(프로그래밍 언어)가 갖춘 형식 시스템은 `impl`(구현), trait(트레이트), struct(구조체) 및 enum(열거형)을 기본으로 구성된다. `impl`이 다른 언어의 클래스와 비슷한 역할을 하며, 상속과 다형성은 트레이트를 통해 제공된다. 트레이트에는 메서드를 정의할 수 있으며, 트레이트에서 선언된 메서드는 `impl`에 의해 struct에 믹스인된다. struct에는 필드를 정의할 수 있으며, 트레이트와 `impl` 자체에는 필드를 정의할 수 없다. enum에는 여러 종류의 형식 범주 변수를 정의할 수 있으며, 수치형, 문자열형, 객체형 등 여러 상태를 선택적으로 가질 수 있다. 다이아몬드 상속 문제를 회피하기 위해 트레이트만 상속이 가능하다.

사용자 정의 타입은 `struct` 또는 `enum` 키워드를 사용하여 생성된다. `struct` 키워드는 여러 관련 값을 그룹화하는 레코드 타입을 나타내는 데 사용된다. `enum`은 런타임에 서로 다른 변형을 가질 수 있으며, 기능은 함수형 프로그래밍 언어에서 발견되는 대수적 데이터 타입과 유사하다. struct와 enum 모두 서로 다른 타입을 가진 필드를 포함할 수 있다. 동일한 타입에 대한 다른 이름은 `type` 키워드를 사용하여 정의할 수 있다.

`impl` 키워드는 사용자 정의 타입에 대한 메서드를 정의할 수 있다. 데이터와 함수는 별도로 정의된다. 구현은 다른 언어의 클래스와 유사한 역할을 수행한다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

변수의 형식을 결정하는 형식 시스템은 정적 타입이며 강력한 타입이다. 정적 타입과 동적 타입의 구분에서 형식은 컴파일 시 모든 변수에 대해 형식을 결정하는 정적 타입을 기본으로 하지만, 트레이트를 포인터를 통해 사용하여 덕 타이핑과 유사한 형식 지정을 할 수 있는 트레이트 객체가 존재한다. 또한, Any 트레이트를 사용하여 런타임 리플렉션을 사용한 동적 타입 지정도 가능하다. 강력한 타입과 약한 타입의 구분에서 형식 지정은 실행 시 변수의 형식을 형 변환 (업캐스팅, 다운캐스팅, 크로스 캐스팅) 및 박싱을 허용하지 않는 강력한 타입 지정을 지원한다. C 언어, 자바는 실행 시 형 변환을 허용하는 약한 타입 지정을 지원하지만, 러스트 언어에서는 변환 대상 형식이 명시되지 않은 상황에서의 형 변환은 인정되지 않는다. 또한, 형식이 확정된 변수에의 대입이나, 시그니처에 의해 형식이 확정된 함수에의 인수 전달 및 반환값 수신 등에서는, 형식 강제를 위한 함수가 정의되어 있으면 이를 암묵적으로 호출할 수 있다.[164]

4. 4. 2. 타입 추론

러스트 컴파일러는 변수에 대입할 때(variable = value), 변수의 형을 값의 형에 기초하여 형 추론한다. 변수의 선언에는 반드시 형을 결정하기 위한 초기값을 필요로 하지 않는다. 변수의 선언 시 초기값이 주어진 경우에는 "변수의 형"은 "초기값의 형"이라고 형 추론이 이루어지지만, 초기값이 주어지지 않은 경우에는 이후 블록 코드 중 그 변수에 값이 처음 대입되었을 때 "좌변의 변수의 형"은 "우변의 대입하는 값의 형"이라고 형 추론이 이루어진다. 변수에의 대입이 형 불일치에 의해 실패한 경우에는 컴파일 시에 에러를 검출한다[165].

4. 4. 3. 다형성 실현

러스트의 더 발전된 기능에는 제네릭 함수의 사용이 포함된다. 제네릭 함수는 제네릭 매개변수를 받아서 동일한 함수를 서로 다른 변수 유형에 적용할 수 있도록 한다. 이 기능은 중복 코드를 줄여주며 매개변수 다형성으로 알려져 있다.

다음 프로그램은 두 개의 값을 더하는 함수로, 덧셈 연산이 제네릭 함수를 사용하여 구현된다.



use std::ops::Add;

// sum은 T라는 한 개의 타입 매개변수를 갖는 제네릭 함수이다.

fn sum(num1: T, num2: T) -> T

where

T: Add, // T는 덧셈이 또 다른 T를 반환하는 Add 트레이트를 구현해야 한다.

{

num1 + num2 // num1 + num2는 Add 트레이트에 의해 제공되는 num1.add(num2)의 구문 설탕이다.

}

fn main() {

let result1 = sum(10, 20);

println!("Sum is: {}", result1); // Sum is: 30

let result2 = sum(10.23, 20.45);

println!("Sum is: {}", result2); // Sum is: 30.68

}



컴파일 시점에, `sum`과 같은 다형성 함수는 코드에서 필요로 하는 특정 타입으로 인스턴스화된다. 이 경우 정수의 합과 부동 소수점의 합이다.

제네릭은 동일한 코드를 반복하지 않고도 서로 다른 타입에 대한 동작을 구현할 수 있도록 하기 위해 함수에서 사용될 수 있다. 제네릭 함수는 실제 타입을 알지 못한 채, 다른 제네릭과 관련하여 작성될 수 있다.

러스트의 타입 시스템은 하스켈 언어의 타입 클래스에서 영감을 받은 트레이트라는 메커니즘을 지원하여 다양한 타입 간의 공유된 동작을 정의한다. 예를 들어, `Add` 트레이트는 덧셈이 가능한 부동 소수점 숫자와 정수에 대해 구현될 수 있으며, `Display` 또는 `Debug` 트레이트는 문자열로 변환될 수 있는 모든 타입에 대해 구현될 수 있다. 트레이트는 실제 타입을 알지 못해도 서로 다른 타입에 대해 공통된 동작 집합을 제공하는 데 사용될 수 있다. 이러한 기능을 임의 다형성이라고 한다.

제네릭 함수는 제네릭 타입이 특정 트레이트 또는 트레이트들을 구현하도록 제약할 수 있다. 예를 들어, `add_one` 함수는 해당 타입이 `Add`를 구현하도록 요구할 수 있다. 이는 제네릭 함수가 정의되자마자 타입 검사를 받을 수 있음을 의미한다. 제네릭의 구현은 C++ 템플릿의 일반적인 구현과 유사하다. 각 인스턴스화에 대해 코드의 별도 복사본이 생성된다. 이것을 모노모프화라고 하며, 자바와 하스켈에서 일반적으로 사용되는 타입 소거 방식과 대조된다. 타입 소거는 `dyn` 키워드(dynamic의 줄임말)를 통해서도 사용할 수 있다. 모노모프화는 사용된 각 타입에 대해 코드를 중복하므로 특정 사용 사례에 대해 더 최적화된 코드를 생성할 수 있지만, 컴파일 시간과 출력 바이너리의 크기도 증가한다.

사용자 정의 타입에 대한 메서드를 정의하는 것 외에도, `impl` 키워드를 사용하여 타입에 대한 트레이트를 구현할 수 있다. 트레이트는 구현 시 추가적인 파생 메서드를 제공할 수 있다. 예를 들어, `Iterator` 트레이트는 `next` 메서드가 해당 타입에 대해 정의되도록 요구한다. `next` 메서드가 정의되면, 트레이트는 `map` 또는 `filter`와 같은 이터레이터에 대한 공통 기능 헬퍼 메서드를 제공할 수 있다.

러스트의 트레이트는 정적 디스패치를 사용하여 구현된다. 이는 모든 값의 형식이 컴파일 시간에 알려진다는 것을 의미한다. 그러나 러스트는 또한 ''트레이트 객체''라고 하는 기능을 사용하여 동적 디스패치를 수행한다. 이는 다형적 연산의 구현이 런타임에 선택되는 다형성의 한 유형이다. 이를 통해 주어진 트레이트를 구현하는 모든 데이터 형식을 기능적으로 동일하게 취급할 수 있는 덕 타이핑과 유사한 동작을 허용한다.[59] 트레이트 객체는 `dyn Tr` 구문을 사용하여 선언되며, 여기서 `Tr`은 트레이트이다. 트레이트 객체는 동적으로 크기가 조정되므로 `Box`와 같은 포인터 뒤에 두어야 한다. 다음 예제는 각 객체를 `Display` 트레이트를 사용하여 출력할 수 있는 객체 목록을 만듭니다.



use std::fmt::Display;

let v: Vec> = vec![

Box::new(3),

Box::new(5.0),

Box::new("hi"),

];

for x in v {

println!("{x}");

}



목록의 요소가 `Display` 트레이트를 구현하지 않으면 컴파일 시간 오류가 발생한다.

구조체의 필드 및 함수의 입출력 값은 특정 트레이트를 구현하는 제네릭 타입을 지정하여 다형성을 실현할 수 있다. 이러한 정의 내에서 제네릭 타입으로 타입이 선언된 변수 및 입출력 값은 해당 트레이트의 특성만 사용할 수 있다. 이는 제네릭 함수가 정의되면 즉시 타입 판별이 가능하다는 것을 의미한다. 이는 C++덕 타이핑에서 구체적인 타입이 인스턴스화될 때까지 판별할 수 없는 템플릿과는 대조적이다. 그러나 Rust의 제네릭 구현은 C++의 템플릿의 전형적인 구현과 유사하며, 인스턴스화될 때마다 코드의 개별 복사본이 생성된다. 이는 단상화[166]라고 불리며, Java나 Haskell에서 일반적으로 사용되는 타입 소거 방식과는 대조적이다. 단상화의 장점은 특정 사용 사례에 최적화된 코드이며, 단점은 결과 바이너리의 컴파일 시간 및 크기가 증가한다는 것이다. Rust의 트레이트를 사용한 다형성 실현은 런타임 오버헤드가 없는 "제로 코스트 추상화"로 표현된다[167].

4. 5. 리소스 관리

시스템 프로그래밍 언어에는 효율적인 리소스 관리 기능이 필수적이다 (예: 메모리·파일 관리). C 언어는 프로그래머가 리소스를 직접 관리하여 높은 효율을 얻을 수 있지만, 메모리 누수와 같은 버그가 발생할 위험을 내포하고 있다. 보다 고급 언어(예: Java)에서는 가비지 컬렉션과 같은 동적 리소스 관리 기구로 높은 안전성을 확보할 수 있지만, 동적 관리의 오버헤드가 항상 따른다.

Rust는 소유권을 중심으로 RAII·참조·차용 검사기 등을 언어 사양으로 통합하여 리소스 관리 검증을 컴파일 시, 정적으로 수행한다. 따라서 동적 관리의 오버헤드를 피하면서 안전성이 보장된 리소스 접근이 가능해졌다 (c.f. 제로 코스트 추상화).

다음은 Rust의 리소스 관리를 뒷받침하는 개별 개념이다.

  • '''소유권'''(Ownership영어)은 리소스 관리의 핵심을 이루는 중요한 개념이다. 하나의 리소스는 하나의 소유자(변수나 블록)에만 연관된다는 제약이 Rust 고유의 리소스 관리 기능으로 존재한다. 이는, 어떤 리소스의 소유권은 어떤 소유자(owner)가 가지고 있다는 식으로 표현된다. 동시에, 리소스의 소유권을 여러 변수가 가질 수는 없다.


이는 C++(C++)의 스마트 포인터의 일종인 `unique_ptr`의 동작과 유사하다.

러스트의 소유권 시스템은 가비지 컬렉션을 사용하지 않고 메모리 안전성을 보장하는 규칙으로 구성되어 있다. 컴파일 시점에 각 값은 해당 값의 ''소유자''라고 하는 변수에 연결되어야 하며, 모든 값은 정확히 하나의 소유자를 가져야 한다.[53] 값은 할당이나 함수 매개변수로 값을 전달하여 서로 다른 소유자 간에 이동한다. 값은 또한 ''빌릴'' 수 있는데, 이는 소유자에게 반환되기 전에 다른 함수로 임시로 전달되는 것을 의미한다.[53][53] 이러한 규칙을 통해 러스트는 댕글링 포인터의 생성 및 사용을 방지할 수 있다.[53][53]

```rust

fn print_string(s: String) {

println!("{}", s);

}

fn main() {

let s = String::from("Hello, World");

print_string(s); // s consumed by print_string

// s has been moved, so cannot be used any more

// another print_string(s); would result in a compile error

}

```

이러한 소유권 규칙 때문에 러스트 타입은 ''선형 타입'' 또는 ''아핀'' 타입이라고 알려져 있는데, 이는 각 값을 정확히 한 번 사용할 수 있다는 의미이다. 이는 값의 소유자가 해당 값의 정확성과 할당 해제에 대한 전적인 책임을 지므로 소프트웨어 오류 격리의 한 형태를 시행한다.[53]

값이 스코프 밖으로 벗어날 때, 해당 값은 소멸자를 실행하여 ''drop''된다. 소멸자는 `Drop` 트레이트를 구현하여 프로그래밍 방식으로 정의할 수 있다. 이는 객체가 drop될 때 해당 객체와 관련된 리소스가 자동으로 닫히거나 해제되므로 파일 핸들, 네트워크 소켓 및 과 같은 리소스를 관리하는 데 도움이 된다.

러스트는 가비지 컬렉션을 사용하지 않는다. 대신 메모리 및 기타 리소스는 "리소스 획득이 초기화다" 규칙[65]을 통해 관리되며, 선택적으로 참조 계수를 사용한다. 러스트는 매우 낮은 오버헤드로 리소스를 결정적으로 관리한다.[66] 값은 기본적으로 스택 기반 메모리 할당으로 할당되며, 모든 동적 할당은 명시적으로 이루어져야 한다.[67]

`&` 기호를 사용하는 내장 참조 유형은 런타임 참조 계수를 포함하지 않는다. 기본 포인터의 안전성과 유효성은 컴파일 시간에 검증되어 댕글링 포인터 및 기타 형태의 정의되지 않은 동작을 방지한다.[53] 러스트의 타입 시스템은 `&T` 형태의 공유, 불변 객체 참조를 `&mut T` 형태의 고유한 가변 참조와 분리한다. 가변 참조는 불변 참조로 강제 변환될 수 있지만 그 반대는 불가능하다.

  • 참조(Reference)는 "타인 소유 값의 일시적인 차용"을 표현하는 값이다.[168] 즉, 참조는 값의 소유권을 원래 소유자에게 둔 채 생성되는, 값에 대한 접근 통로이다.[169] 참조를 통해 참조 대상 값을 읽고 쓸 수 있는 반면, 참조를 해제해도 (소유권이 없으므로) 참조 대상 값은 계속 존재한다. 참조는 항상 유효한 참조 대상을 가리키도록 보장된다.[170][171] 참조를 얻는 것을 차용(borrow)이라고 한다.[168]


참조는 몇 가지 문제를 해결하기 위해 러스트에 도입되었다. 우선 값에 대한 접근을 소유자에게만 제한할 경우, 소유자 변수가 블록/함수 내부에서 외부로 전달되어 불필요해진다.[172] 값의 소유권을 가지지 않고도 접근을 가능하게 하는, 통로, 프록시 또는 별칭과 같은 객체가 있다면 이 문제는 해결된다. 그러나 단순히 접근 객체를 전달하면 그 유효 범위가 불분명해져 댕글링 참조가 발생할 수 있다. 이는 참조와 참조 대상의 생존 기간 등을 비교함으로써 정적으로 감지할 수 있다(차용 검사기). 이를 통해 참조는 항상 유효하며, 널 참조 검사도 불필요해진다.

차용을 나타내는 표현식을 차용 표현식 `&expr` (borrow expression)이라고 한다.[173] 참조와 관련된 타입 및 연산자는 다음과 같다.

표. 참조와 관련된 타입 및 연산자
참조 타입 (reference type)[174]차용 연산자 (borrow operator)[175]
공유 참조 타입 `&T` (shared reference type)[176]공유 차용 연산자 `&` (shared borrow operator)[177]
가변 참조 타입 `&mut T` (mutable reference type)[178]가변 차용 연산자 `&mut` (mutable borrow operator)[179]



연산자 `&`를 사용한 표현식 `&expr`의 평가를 통해 타입 `&T`의 값을 얻는다. `&mut`에서도 마찬가지이다.

공유 참조 타입은 참조 대상의 읽기만 가능하고 수정은 불가능하지만, 값이 불변이므로 동일한 값을 가리키는 여러 개의 공유 참조를 생성할 수 있다.[180] 참조는 `Copy` 트레이트를 통해 이동이 아닌 복사로 전달된다.[181] 가변 참조 타입은 두 가지 모두 가능하지만, 값이 가변이므로 동일한 값을 가리키는 다른 참조를 생성할 수 없다.[182] 따라서 참조는 `Copy` 트레이트를 갖지 않으며 복사가 아닌 이동으로 전달된다.[183]

러스트는 데이터 부재를 나타내기 위해 널 포인터를 사용하지 않는다. 그렇게 하면 널 역참조로 이어질 수 있기 때문이다. 따라서 기본 `&` 및 `&mut` 참조는 null이 아님을 보장한다. 대신 러스트는 이러한 목적으로 `Option`을 사용한다. `Some(T)`는 값이 있음을 나타내고 `None`은 널 포인터와 유사하다. Option은 "널 포인터 최적화"를 구현하여 null 값을 가질 수 없는 타입(예: 참조 또는 `NonZero` 타입)에 대한 공간 오버헤드를 피한다.[52]

러스트의 포인터 및 참조 기본 타입 요약
타입설명예시
참조 (불변 및 가변)
힙에 할당된 값에 대한 포인터



참조와 달리 raw 포인터 타입 `*const` 및 `*mut`는 null일 수 있다. 그러나 `unsafe` 블록을 사용하여 코드가 명시적으로 unsafe로 선언되지 않으면 역참조할 수 없다. 역참조와 달리 raw 포인터의 생성은 안전한 러스트 코드 내에서 허용된다.


  • 이미 해제된 리소스를 계속 가리키는 참조는 버그를 유발한다(예: 댕글링 포인터). 만약 이를 정적으로 검증할 수 있다면, 오버헤드 없이 안전성을 확보할 수 있다. 또한 검증을 통해 부정한 참조를 피할 수 있으므로 참조에 대한 널 대입이 불필요해지고, 널 포인터 검사를 불필요하게 만들 수 있다.


러스트에서는 '''차용 검사기'''(borrow checker영어, '''보로 체커''')에 의해 소유권의 경합 및 부정 이용을 정적으로 검증한다. 소유권이 해제된 리소스를 가리키는 참조는 무효이며, 사용한 경우에는 컴파일 오류가 발생한다. 보로 체커는 참조에 대해서도 라이프타임(lifetimes)으로서 리소스의 생존 기간을 검증한다. 이를 통해 널 포인터나 댕글링 포인터, 리소스 이용 경합을 제한한 메모리 안전성을 실현하고 있다.

객체 수명은 참조가 유효한 기간, 즉 객체 생성부터 소멸까지의 기간을 의미한다.[54] 이러한 ''수명''은 모든 Rust 참조 타입에 암묵적으로 연결되어 있다. 종종 추론되지만, 명명된 수명 매개변수를 사용하여 명시적으로 나타낼 수도 있다.[55]

Rust의 수명은 어휘적으로 범위가 지정된 것으로 생각할 수 있으며, 이는 객체 수명의 기간이 변수가 유효한 소스 코드 위치 집합에서 추론됨을 의미한다. 예를 들어, 지역 변수에 대한 참조는 정의된 블록에 해당하는 수명을 갖는다.

Rust 컴파일러의 '''차용 검사기'''는 참조가 관련된 수명이 유효한 소스 코드 위치에서만 사용되도록 강제한다.[56] 변수 에 대한 참조를 에 저장하는 것은 유효하다. 변수 가 변수 ()보다 더 긴 수명()을 갖기 때문이다. 그러나 의 수명이 짧으면 차용 검사기는 프로그램을 거부한다.

참조된 변수()의 수명이 참조를 보유하는 변수()의 수명보다 짧기 때문에, 차용 검사기는 오류를 발생시켜 가 범위를 벗어나 사용되는 것을 방지한다.

수명은 함수 인수에 명시적인 ''수명 매개변수''를 사용하여 나타낼 수 있다.

사용자 정의 타입이 데이터에 대한 참조를 보유하는 경우 수명 매개변수를 사용해야 한다.

컴파일러에서 소유권과 수명은 함께 작동하여 댕글링 포인터와 같은 메모리 안전 문제를 방지한다.[57][58]

러스트는 메모리 안전을 위해 설계되었다. 널 포인터, 댕글링 포인터, 또는 데이터 레이스를 허용하지 않는다.[60][61][62][63] 데이터 값은 고정된 형식 집합을 통해서만 초기화할 수 있으며, 이 형식은 모두 입력이 이미 초기화되어 있어야 한다.[64]

  • 러스트의 메모리 할당은 기본적으로 스택 메모리를 사용하며, 힙 메모리를 사용한 메모리 할당은 `Box`나 `Vec` 등의 특정 타입으로 제한적으로 사용된다.


컴파일 시에 타입의 크기를 결정할 수 없는 가변 길이 배열을 나타내는 타입은 힙 메모리를 사용하는 `Box` 타입을 사용하여 리소스를 관리한다. `Box` 리소스 자체는 스택 메모리에서 관리되지만, `Box` 리소스가 소유권을 갖는 실체의 리소스는 힙 메모리에서 관리된다. 표준 힙 메모리 할당에는 시스템 할당기를 사용하지만[184], 대상 플랫폼이나 빌드 시의 지정에 따라 다른 메모리 할당 API를 사용할 수도 있다. 힙 메모리는 스택 메모리에 비해 속도 성능이 떨어지므로, 필요할 때만 제한적으로 사용된다.

  • 러스트는 실행 시 경계 검사를 수행한다. 이를 통해 버퍼 오버런을 비롯한 메모리 액세스에 대한 안전성을 확보한다. 이 기능은 제로 코스트 추상화가 아닌 실행 시 명령이므로, 안전성을 얻는 대신 약간의 성능 오버헤드가 발생한다. 다른 시스템 프로그래밍 언어로 대표적인 C 언어나 C++는 경계 검사를 강제하지 않으므로, 러스트의 특징 중 하나가 된다.

  • '''라이프타임'''()은 제네릭 타입의 일종으로, 리소스나 그 리소스에 대한 참조의 생존 기간을 나타낸다.[185]


객체 수명은 참조가 유효한 기간, 즉 객체 생성부터 소멸까지의 기간을 의미한다.[54] 이러한 ''수명''은 모든 Rust 참조 타입에 암묵적으로 연결되어 있다. 종종 추론되지만, 명명된 수명 매개변수(종종 'a, 'b 등으로 표시됨)를 사용하여 명시적으로 나타낼 수도 있다.[55]

Rust의 수명은 어휘적으로 범위가 지정된 것으로 생각할 수 있으며, 이는 객체 수명의 기간이 변수가 유효한 소스 코드(즉, 함수, 줄 및 열 번호) 위치 집합에서 추론됨을 의미한다. 예를 들어, 지역 변수에 대한 참조는 정의된 블록에 해당하는 수명을 갖는다.

```rust

fn main() {

let x = 5; // ------------------+- 수명 'a

// |

let r = &x; // -+-- 수명 'b |

// | |

println!("r: {}", r); // | |

// | |

// -+ |

} // ------------------+

```

그런 다음 Rust 컴파일러의 차용 검사기는 참조가 관련된 수명이 유효한 소스 코드 위치에서만 사용되도록 강제한다.[56] 위의 예에서 변수 x에 대한 참조를 r에 저장하는 것은 유효하다. 변수 x가 변수 r('b)보다 더 긴 수명('a)을 갖기 때문이다. 그러나 x의 수명이 짧으면 차용 검사기는 프로그램을 거부한다.

```rust

fn main() {

let r; // ------------------+- 수명 'a

// |

{ // |

let x = 5; // -+-- 수명 'b |

r = &x; // | | // 여기서 오류: x의 수명이 충분하지 않음

} // -| |

// |

println!("r: {}", r); // |

} // ------------------+

```

참조된 변수('b)의 수명이 참조를 보유하는 변수('a)의 수명보다 짧기 때문에, 차용 검사기는 오류를 발생시켜 x가 범위를 벗어나 사용되는 것을 방지한다.

수명은 함수 인수에 명시적인 ''수명 매개변수''를 사용하여 나타낼 수 있다. 예를 들어, 다음 코드는 함수에서 반환된 참조가 prefix의 수명이 ''아니라'' original과 동일한 수명을 갖는다고 지정한다.

```rust

fn remove_prefix<'a>(mut original: &'a str, prefix: &str) -> &'a str {

if original.starts_with(prefix) {

original = original[prefix.len()..];

}

original

}

```

사용자 정의 타입이 데이터에 대한 참조를 보유하는 경우 수명 매개변수를 사용해야 한다. 아래 예제는 문자열에서 일부 구성 옵션을 구문 분석하고 옵션을 포함하는 구조체를 생성한다. `parse_config` 함수는 또한 명시적으로 수명 매개변수를 정의할 필요성을 줄이는 수명 생략을 보여준다.

```rust

use std::collections::HashMap;

// 이 구조체는 하나의 수명 매개변수 'src를 갖는다. 이름은 구조체의 정의 내에서만 사용된다.

#[derive(Debug)]

struct Config<'src> {

hostname: &'src str,

username: &'src str,

}

// 이 경우 '_ 수명 매개변수는 인수 `config`의 타입에 연결된 익명 수명을 나타낸다.

fn parse_config(config: &str) -> Config<'_> {

let key_values: HashMap<_, _> = config

.lines()

.filter(|line| !line.starts_with('#'))

.filter_map(|line| line.split_once('='))

.map(|(key, value)| (key.trim(), value.trim()))

.collect();

Config {

hostname: key_values["hostname"],

username: key_values["username"],

}

}

fn main() {

let config = parse_config(

r#"hostname = foobar

username=barfoo"#,

);

println!("Parsed config: {:#?}", config);

}

```

컴파일러에서 소유권과 수명은 함께 작동하여 댕글링 포인터와 같은 메모리 안전 문제를 방지한다.[57][58]

참조를 함수나 메서드와 주고받거나, 구조체나 열거형 등 다른 데이터 타입에 저장하면 참조의 생존 기간이 참조를 정의한 스코프만으로는 결정되지 않게 된다. 이 경우, 참조나 참조 대상 리소스에 대해 라이프타임의 부가가 필요하게 된다. 라이프타임은 'lifetime 형식으로 기술한다. 라이프타임을 참조 타입에 부가하는 경우에는 & 바로 뒤에, 그 외 타입에 대해서는 제네릭 타입으로 부가한다. 이 외에도, 다른 제네릭 타입에 대해 라이프타임을 부가할 수도 있다. 특히, 어떤 라이프타임에 대해 다른 라이프타임을 경계 조건으로 주어, 둘 중 하나가 다른 하나보다 더 오래 생존할 것을 요구할 수 있다.[186]

보로 체커는 라이프타임을 가진 변수에 대해, 해당 변수가 가리키는 참조 대상이나 리소스의 생존 기간이 라이프타임에 의해 요구되는 생존 기간을 만족하는지 여부를 검사한다. 검사에 실패한 경우에는 컴파일 에러로 처리한다. 주의해야 할 점은, 라이프타임을 부여함으로써 참조 대상이나 리소스의 생존 기간을 연장할 수는 없다는 것이다. 이들의 생존 기간은 어디까지나 그것들을 정의하고 사용하는 스코프에 의해 결정되므로, 라이프타임 검사에서 에러가 발생한 경우에는 참조 대상의 생존 기간을 수정해야 한다.

함수나 메서드의 정의에서, 부가해야 할 라이프타임에, 어떤 특정 패턴이 존재한다는 것이 알려져 있다. 그러한 패턴에 따라 라이프타임을 지정하고 싶은 경우에는, 라이프타임의 수동 부가를 생략하고, 컴파일러가 라이프타임을 자동 부가하도록 할 수 있다. 이 기능은 '''라이프타임 엘리전'''()[187]이라고 불린다. 라이프타임 엘리전 패턴 이외의 라이프타임이 필요한 경우에는 라이프타임 엘리전을 사용할 수 없으며, 라이프타임을 명시적으로 부가해야 한다.

함수의 타입을 정의할 때, 해당 인자나 반환값이 참조를 포함하는 경우에는 종종 라이프타임이 필요하지만, 그 라이프타임이 가리키는 생존 기간이 함수의 타입만으로는 결정되지 않고, 그 타입에 포함된 함수나 클로저를 실제로 정의해야 생존 기간도 결정되는 경우가 있다. 이러한 경우, 함수의 타입에서 사용하는 라이프타임을, 함수 타입으로서는 임의의 생존 기간을 가져도 괜찮다고 정할 수 있다. 그러한 라이프타임은 '''고차 트레이트 바운드'''(, HRTB)[188]로 정의한다. HRTB를 사용하여 정의한 함수 타입은 단일 타입이 아니라, 라이프타임이 가질 수 있는 모든 경우의 수만큼 있는 타입의 집합이 되며, 이론상 "함수의 집합"이 되는 데서 유래한다.

  • 러스트의 특징 중 하나는 변수를 메모리 상에서 자유롭게 이동할 수 있다는 것이다.[189] 이를 통해 함수나 메서드를 호출할 때 변수를 값으로 전달할 수 있다. 또한, 이러한 조작이나 대입 등에서의 소유권 이동 역시 이 특징에 의존한다.


`Box`형( `T`는 타입, 이하 동일)과 같은 스마트 포인터, 그리고 `Vec`형처럼 가변 길이 데이터를 가리키는 포인터의 경우, 포인터가 가리키는 데이터는 일반적으로 이동하지 않지만, 포인터 자체는 이동한다. 즉, 포인터의 값을 전달하는 동작이 된다.

변수의 이동을 방지하고 싶을 경우, 일반적으로 `Pin

`형( `P`는 트레이트 `Pointer`를 갖는 타입, 전형적으로는 스마트 포인터)을 사용한다. 이 타입은 `Box`형이나 `&mut T`형의 취득을 금지하며, 이를 통해 `Pin

`형이 가리키는 데이터의 이동을 막는다. `Pin

`형에서 `Pin<&mut T>`형을 얻는 것은 가능하며, 이를 이용하여 데이터의 이동을 막으면서 변경하는 것은 가능하다. 또한, `Pin

`형 자체를 값 전달 등으로 이동하는 것도 가능하다.

러스트에서 변수의 이동을 막아야 할 필요가 있는 상황으로는, 주로 다음과 같은 경우가 있다.


  • 구조체형에서, 자신 또는 해당 필드에 대한 포인터를 가질 경우.[190]
  • 변수의 주소를 러스트 외부의 라이브러리 등으로 전달하는 경우.

4. 5. 1. 소유권

러스트의 소유권 시스템은 가비지 컬렉션을 사용하지 않고 메모리 안전성을 보장하는 규칙으로 구성되어 있다. 컴파일 시점에 각 값은 해당 값의 ''소유자''라고 하는 변수에 연결되어야 하며, 모든 값은 정확히 하나의 소유자를 가져야 한다.[53] 값은 할당이나 함수 매개변수로 값을 전달하여 서로 다른 소유자 간에 이동한다. 값은 또한 ''빌릴'' 수 있는데, 이는 소유자에게 반환되기 전에 다른 함수로 임시로 전달되는 것을 의미한다.[53][53] 이러한 규칙을 통해 러스트는 댕글링 포인터의 생성 및 사용을 방지할 수 있다.[53][53]

```rust

fn print_string(s: String) {

println!("{}", s);

}

fn main() {

let s = String::from("Hello, World");

print_string(s); // s consumed by print_string

// s has been moved, so cannot be used any more

// another print_string(s); would result in a compile error

}

```

이러한 소유권 규칙 때문에 러스트 타입은 ''선형 타입'' 또는 ''아핀'' 타입이라고 알려져 있는데, 이는 각 값을 정확히 한 번 사용할 수 있다는 의미이다. 이는 값의 소유자가 해당 값의 정확성과 할당 해제에 대한 전적인 책임을 지므로 소프트웨어 오류 격리의 한 형태를 시행한다.[53]

값이 스코프 밖으로 벗어날 때, 해당 값은 소멸자를 실행하여 ''drop''된다. 소멸자는 `Drop` 트레이트를 구현하여 프로그래밍 방식으로 정의할 수 있다. 이는 객체가 drop될 때 해당 객체와 관련된 리소스가 자동으로 닫히거나 해제되므로 파일 핸들, 네트워크 소켓 및 과 같은 리소스를 관리하는 데 도움이 된다.

러스트는 가비지 컬렉션을 사용하지 않는다. 대신 메모리 및 기타 리소스는 "리소스 획득이 초기화다" 규칙[65]을 통해 관리되며, 선택적으로 참조 계수를 사용한다. 러스트는 매우 낮은 오버헤드로 리소스를 결정적으로 관리한다.[66] 값은 기본적으로 스택 기반 메모리 할당으로 할당되며, 모든 동적 할당은 명시적으로 이루어져야 한다.[67]

`&` 기호를 사용하는 내장 참조 유형은 런타임 참조 계수를 포함하지 않는다. 기본 포인터의 안전성과 유효성은 컴파일 시간에 검증되어 댕글링 포인터 및 기타 형태의 정의되지 않은 동작을 방지한다.[53] 러스트의 타입 시스템은 `&T` 형태의 공유, 불변 객체 참조를 `&mut T` 형태의 고유한 가변 참조와 분리한다. 가변 참조는 불변 참조로 강제 변환될 수 있지만 그 반대는 불가능하다.

'''소유권'''(Ownership영어)은 리소스 관리의 핵심을 이루는 중요한 개념이다. 하나의 리소스는 하나의 소유자(변수나 블록)에만 연관된다는 제약이 Rust 고유의 리소스 관리 기능으로 존재한다. 이는, 어떤 리소스의 소유권은 어떤 소유자(owner)가 가지고 있다는 식으로 표현된다. 동시에, 리소스의 소유권을 여러 변수가 가질 수는 없다.

이는 C++(C++)의 스마트 포인터의 일종인 `unique_ptr`의 동작과 유사하다.

4. 5. 2. 참조

참조(Reference)는 "타인 소유 값의 일시적인 차용"을 표현하는 값이다.[168] 즉, 참조는 값의 소유권을 원래 소유자에게 둔 채 생성되는, 값에 대한 접근 통로이다.[169] 참조를 통해 참조 대상 값을 읽고 쓸 수 있는 반면, 참조를 해제해도 (소유권이 없으므로) 참조 대상 값은 계속 존재한다. 참조는 항상 유효한 참조 대상을 가리키도록 보장된다.[170][171] 참조를 얻는 것을 차용(borrow)이라고 한다.[168]

참조는 몇 가지 문제를 해결하기 위해 러스트에 도입되었다. 우선 값에 대한 접근을 소유자에게만 제한할 경우, 소유자 변수가 블록/함수 내부에서 외부로 전달되어 불필요해진다.[172] 값의 소유권을 가지지 않고도 접근을 가능하게 하는, 통로, 프록시 또는 별칭과 같은 객체가 있다면 이 문제는 해결된다. 그러나 단순히 접근 객체를 전달하면 그 유효 범위가 불분명해져 댕글링 참조가 발생할 수 있다. 이는 참조와 참조 대상의 생존 기간 등을 비교함으로써 정적으로 감지할 수 있다(차용 검사기). 이를 통해 참조는 항상 유효하며, 널 참조 검사도 불필요해진다.

차용을 나타내는 표현식을 차용 표현식 `&expr` (borrow expression)이라고 한다.[173] 참조와 관련된 타입 및 연산자는 다음과 같다.

표. 참조와 관련된 타입 및 연산자
참조 타입 (reference type)[174]차용 연산자 (borrow operator)[175]
공유 참조 타입 `&T` (shared reference type)[176]공유 차용 연산자 `&` (shared borrow operator)[177]
가변 참조 타입 `&mut T` (mutable reference type)[178]가변 차용 연산자 `&mut` (mutable borrow operator)[179]



연산자 `&`를 사용한 표현식 `&expr`의 평가를 통해 타입 `&T`의 값을 얻는다. `&mut`에서도 마찬가지이다.

공유 참조 타입은 참조 대상의 읽기만 가능하고 수정은 불가능하지만, 값이 불변이므로 동일한 값을 가리키는 여러 개의 공유 참조를 생성할 수 있다.[180] 참조는 `Copy` 트레이트를 통해 이동이 아닌 복사로 전달된다.[181] 가변 참조 타입은 두 가지 모두 가능하지만, 값이 가변이므로 동일한 값을 가리키는 다른 참조를 생성할 수 없다.[182] 따라서 참조는 `Copy` 트레이트를 갖지 않으며 복사가 아닌 이동으로 전달된다.[183]

러스트는 데이터 부재를 나타내기 위해 널 포인터를 사용하지 않는다. 그렇게 하면 널 역참조로 이어질 수 있기 때문이다. 따라서 기본 `&` 및 `&mut` 참조는 null이 아님을 보장한다. 대신 러스트는 이러한 목적으로 `Option`을 사용한다. `Some(T)`는 값이 있음을 나타내고 `None`은 널 포인터와 유사하다. Option은 "널 포인터 최적화"를 구현하여 null 값을 가질 수 없는 타입(예: 참조 또는 `NonZero` 타입)에 대한 공간 오버헤드를 피한다.[52]

러스트의 포인터 및 참조 기본 타입 요약
타입설명예시
참조 (불변 및 가변)
{{Plain list|* Boxrs힙에 할당된 값에 대한 포인터{{Plain list|* `let boxed = Box::new(0);`



참조와 달리 raw 포인터 타입 `*const` 및 `*mut`는 null일 수 있다. 그러나 `unsafe` 블록을 사용하여 코드가 명시적으로 unsafe로 선언되지 않으면 역참조할 수 없다. 역참조와 달리 raw 포인터의 생성은 안전한 러스트 코드 내에서 허용된다.

4. 5. 3. 차용 검사기

객체 수명은 참조가 유효한 기간, 즉 객체 생성부터 소멸까지의 기간을 의미한다.[54] 이러한 ''수명''은 모든 Rust 참조 타입에 암묵적으로 연결되어 있다. 종종 추론되지만, 명명된 수명 매개변수를 사용하여 명시적으로 나타낼 수도 있다.[55]

Rust의 수명은 어휘적으로 범위가 지정된 것으로 생각할 수 있으며, 이는 객체 수명의 기간이 변수가 유효한 소스 코드 위치 집합에서 추론됨을 의미한다. 예를 들어, 지역 변수에 대한 참조는 정의된 블록에 해당하는 수명을 갖는다.

Rust 컴파일러의 '''차용 검사기'''는 참조가 관련된 수명이 유효한 소스 코드 위치에서만 사용되도록 강제한다.[56] 변수 에 대한 참조를 에 저장하는 것은 유효하다. 변수 가 변수 ()보다 더 긴 수명()을 갖기 때문이다. 그러나 의 수명이 짧으면 차용 검사기는 프로그램을 거부한다.

참조된 변수()의 수명이 참조를 보유하는 변수()의 수명보다 짧기 때문에, 차용 검사기는 오류를 발생시켜 가 범위를 벗어나 사용되는 것을 방지한다.

수명은 함수 인수에 명시적인 ''수명 매개변수''를 사용하여 나타낼 수 있다.

사용자 정의 타입이 데이터에 대한 참조를 보유하는 경우 수명 매개변수를 사용해야 한다.

컴파일러에서 소유권과 수명은 함께 작동하여 댕글링 포인터와 같은 메모리 안전 문제를 방지한다.[57][58]

러스트는 메모리 안전을 위해 설계되었다. 널 포인터, 댕글링 포인터, 또는 데이터 레이스를 허용하지 않는다.[60][61][62][63] 데이터 값은 고정된 형식 집합을 통해서만 초기화할 수 있으며, 이 형식은 모두 입력이 이미 초기화되어 있어야 한다.[64]

이미 해제된 리소스를 계속 가리키는 참조는 버그를 유발한다(예: 댕글링 포인터). 만약 이를 정적으로 검증할 수 있다면, 오버헤드 없이 안전성을 확보할 수 있다. 또한 검증을 통해 부정한 참조를 피할 수 있으므로 참조에 대한 널 대입이 불필요해지고, 널 포인터 검사를 불필요하게 만들 수 있다.

러스트에서는 '''차용 검사기'''(borrow checker영어, '''보로 체커''')에 의해 소유권의 경합 및 부정 이용을 정적으로 검증한다. 소유권이 해제된 리소스를 가리키는 참조는 무효이며, 사용한 경우에는 컴파일 오류가 발생한다. 보로 체커는 참조에 대해서도 라이프타임(lifetimes)으로서 리소스의 생존 기간을 검증한다. 이를 통해 널 포인터나 댕글링 포인터, 리소스 이용 경합을 제한한 메모리 안전성을 실현하고 있다.

4. 5. 4. 특이한 리소스 타입

러스트의 메모리 할당은 기본적으로 스택 메모리를 사용하며, 힙 메모리를 사용한 메모리 할당은 `Box`나 `Vec` 등의 특정 타입으로 제한적으로 사용된다.

컴파일 시에 타입의 크기를 결정할 수 없는 가변 길이 배열을 나타내는 타입은 힙 메모리를 사용하는 `Box` 타입을 사용하여 리소스를 관리한다. `Box` 리소스 자체는 스택 메모리에서 관리되지만, `Box` 리소스가 소유권을 갖는 실체의 리소스는 힙 메모리에서 관리된다. 표준 힙 메모리 할당에는 시스템 할당기를 사용하지만[184], 대상 플랫폼이나 빌드 시의 지정에 따라 다른 메모리 할당 API를 사용할 수도 있다. 힙 메모리는 스택 메모리에 비해 속도 성능이 떨어지므로, 필요할 때만 제한적으로 사용된다.

4. 5. 5. 경계 검사

러스트는 실행 시 경계 검사를 수행한다. 이를 통해 버퍼 오버런을 비롯한 메모리 액세스에 대한 안전성을 확보한다. 이 기능은 제로 코스트 추상화가 아닌 실행 시 명령이므로, 안전성을 얻는 대신 약간의 성능 오버헤드가 발생한다. 다른 시스템 프로그래밍 언어로 대표적인 C 언어나 C++는 경계 검사를 강제하지 않으므로, 러스트의 특징 중 하나가 된다.

4. 5. 6. 라이프타임

객체 수명은 참조가 유효한 기간, 즉 객체 생성부터 소멸까지의 기간을 의미한다.[54] 이러한 ''수명''은 모든 Rust 참조 타입에 암묵적으로 연결되어 있다. 종종 추론되지만, 명명된 수명 매개변수(종종 'a, 'b 등으로 표시됨)를 사용하여 명시적으로 나타낼 수도 있다.[55]

Rust의 수명은 어휘적으로 범위가 지정된 것으로 생각할 수 있으며, 이는 객체 수명의 기간이 변수가 유효한 소스 코드(즉, 함수, 줄 및 열 번호) 위치 집합에서 추론됨을 의미한다. 예를 들어, 지역 변수에 대한 참조는 정의된 블록에 해당하는 수명을 갖는다.

```rust

fn main() {

let x = 5; // ------------------+- 수명 'a

// |

let r = &x; // -+-- 수명 'b |

// | |

println!("r: {}", r); // | |

// | |

// -+ |

} // ------------------+

```

그런 다음 Rust 컴파일러의 차용 검사기는 참조가 관련된 수명이 유효한 소스 코드 위치에서만 사용되도록 강제한다.[56] 위의 예에서 변수 x에 대한 참조를 r에 저장하는 것은 유효하다. 변수 x가 변수 r('b)보다 더 긴 수명('a)을 갖기 때문이다. 그러나 x의 수명이 짧으면 차용 검사기는 프로그램을 거부한다.

```rust

fn main() {

let r; // ------------------+- 수명 'a

// |

{ // |

let x = 5; // -+-- 수명 'b |

r = &x; // | | // 여기서 오류: x의 수명이 충분하지 않음

} // -| |

// |

println!("r: {}", r); // |

} // ------------------+

```

참조된 변수('b)의 수명이 참조를 보유하는 변수('a)의 수명보다 짧기 때문에, 차용 검사기는 오류를 발생시켜 x가 범위를 벗어나 사용되는 것을 방지한다.

수명은 함수 인수에 명시적인 ''수명 매개변수''를 사용하여 나타낼 수 있다. 예를 들어, 다음 코드는 함수에서 반환된 참조가 prefix의 수명이 ''아니라'' original과 동일한 수명을 갖는다고 지정한다.

```rust

fn remove_prefix<'a>(mut original: &'a str, prefix: &str) -> &'a str {

if original.starts_with(prefix) {

original = original[prefix.len()..];

}

original

}

```

사용자 정의 타입이 데이터에 대한 참조를 보유하는 경우 수명 매개변수를 사용해야 한다. 아래 예제는 문자열에서 일부 구성 옵션을 구문 분석하고 옵션을 포함하는 구조체를 생성한다. `parse_config` 함수는 또한 명시적으로 수명 매개변수를 정의할 필요성을 줄이는 수명 생략을 보여준다.

```rust

use std::collections::HashMap;

// 이 구조체는 하나의 수명 매개변수 'src를 갖는다. 이름은 구조체의 정의 내에서만 사용된다.

#[derive(Debug)]

struct Config<'src> {

hostname: &'src str,

username: &'src str,

}

// 이 경우 '_ 수명 매개변수는 인수 `config`의 타입에 연결된 익명 수명을 나타낸다.

fn parse_config(config: &str) -> Config<'_> {

let key_values: HashMap<_, _> = config

.lines()

.filter(|line| !line.starts_with('#'))

.filter_map(|line| line.split_once('='))

.map(|(key, value)| (key.trim(), value.trim()))

.collect();

Config {

hostname: key_values["hostname"],

username: key_values["username"],

}

}

fn main() {

let config = parse_config(

r#"hostname = foobar

username=barfoo"#,

);

println!("Parsed config: {:#?}", config);

}

```

컴파일러에서 소유권과 수명은 함께 작동하여 댕글링 포인터와 같은 메모리 안전 문제를 방지한다.[57][58]

'''라이프타임'''()은 제네릭 타입의 일종으로, 리소스나 그 리소스에 대한 참조의 생존 기간을 나타낸다.[185]

참조를 함수나 메서드와 주고받거나, 구조체나 열거형 등 다른 데이터 타입에 저장하면 참조의 생존 기간이 참조를 정의한 스코프만으로는 결정되지 않게 된다. 이 경우, 참조나 참조 대상 리소스에 대해 라이프타임의 부가가 필요하게 된다. 라이프타임은 'lifetime 형식으로 기술한다. 라이프타임을 참조 타입에 부가하는 경우에는 & 바로 뒤에, 그 외 타입에 대해서는 제네릭 타입으로 부가한다. 이 외에도, 다른 제네릭 타입에 대해 라이프타임을 부가할 수도 있다. 특히, 어떤 라이프타임에 대해 다른 라이프타임을 경계 조건으로 주어, 둘 중 하나가 다른 하나보다 더 오래 생존할 것을 요구할 수 있다.[186]

보로 체커는 라이프타임을 가진 변수에 대해, 해당 변수가 가리키는 참조 대상이나 리소스의 생존 기간이 라이프타임에 의해 요구되는 생존 기간을 만족하는지 여부를 검사한다. 검사에 실패한 경우에는 컴파일 에러로 처리한다. 주의해야 할 점은, 라이프타임을 부여함으로써 참조 대상이나 리소스의 생존 기간을 연장할 수는 없다는 것이다. 이들의 생존 기간은 어디까지나 그것들을 정의하고 사용하는 스코프에 의해 결정되므로, 라이프타임 검사에서 에러가 발생한 경우에는 참조 대상의 생존 기간을 수정해야 한다.

함수나 메서드의 정의에서, 부가해야 할 라이프타임에, 어떤 특정 패턴이 존재한다는 것이 알려져 있다. 그러한 패턴에 따라 라이프타임을 지정하고 싶은 경우에는, 라이프타임의 수동 부가를 생략하고, 컴파일러가 라이프타임을 자동 부가하도록 할 수 있다. 이 기능은 '''라이프타임 엘리전'''()[187]이라고 불린다. 라이프타임 엘리전 패턴 이외의 라이프타임이 필요한 경우에는 라이프타임 엘리전을 사용할 수 없으며, 라이프타임을 명시적으로 부가해야 한다.

함수의 타입을 정의할 때, 해당 인자나 반환값이 참조를 포함하는 경우에는 종종 라이프타임이 필요하지만, 그 라이프타임이 가리키는 생존 기간이 함수의 타입만으로는 결정되지 않고, 그 타입에 포함된 함수나 클로저를 실제로 정의해야 생존 기간도 결정되는 경우가 있다. 이러한 경우, 함수의 타입에서 사용하는 라이프타임을, 함수 타입으로서는 임의의 생존 기간을 가져도 괜찮다고 정할 수 있다. 그러한 라이프타임은 '''고차 트레이트 바운드'''(, HRTB)[188]로 정의한다. HRTB를 사용하여 정의한 함수 타입은 단일 타입이 아니라, 라이프타임이 가질 수 있는 모든 경우의 수만큼 있는 타입의 집합이 되며, 이론상 "함수의 집합"이 되는 데서 유래한다.

4. 5. 7. 이동

러스트의 특징 중 하나는 변수를 메모리 상에서 자유롭게 이동할 수 있다는 것이다.[189] 이를 통해 함수나 메서드를 호출할 때 변수를 값으로 전달할 수 있다. 또한, 이러한 조작이나 대입 등에서의 소유권 이동 역시 이 특징에 의존한다.

`Box`형( `T`는 타입, 이하 동일)과 같은 스마트 포인터, 그리고 `Vec`형처럼 가변 길이 데이터를 가리키는 포인터의 경우, 포인터가 가리키는 데이터는 일반적으로 이동하지 않지만, 포인터 자체는 이동한다. 즉, 포인터의 값을 전달하는 동작이 된다.

변수의 이동을 방지하고 싶을 경우, 일반적으로 `Pin

`형( `P`는 트레이트 `Pointer`를 갖는 타입, 전형적으로는 스마트 포인터)을 사용한다. 이 타입은 `Box`형이나 `&mut T`형의 취득을 금지하며, 이를 통해 `Pin

`형이 가리키는 데이터의 이동을 막는다. `Pin

`형에서 `Pin<&mut T>`형을 얻는 것은 가능하며, 이를 이용하여 데이터의 이동을 막으면서 변경하는 것은 가능하다. 또한, `Pin

`형 자체를 값 전달 등으로 이동하는 것도 가능하다.

러스트에서 변수의 이동을 막아야 할 필요가 있는 상황으로는, 주로 다음과 같은 경우가 있다.


  • 구조체형에서, 자신 또는 해당 필드에 대한 포인터를 가질 경우.[190]
  • 변수의 주소를 러스트 외부의 라이브러리 등으로 전달하는 경우.

4. 6. 라이브러리

러스트의 라이브러리는 크레이트(crate)라는 명칭으로 제공된다. 많은 크레이트는 [https://crates.io crates.io]에서 공개된다. 해당 사이트는 버전별 소스 코드를 아카이브로 제공하고 있다. 크레이트는 반드시 crates.io에 등록될 필요는 없으며, 웹 서버파일 시스템을 가리키는 URI로 지정할 수도 있다.[191] 라이브러리는 소스 코드 프로젝트로 배포되는 것이 일반적이지만, 컴파일된 바이너리 라이브러리 파일로 출력하는 것도 가능하다.[192] 스태틱 라이브러리(확장자 `rlib`) 및 다이내믹 라이브러리(확장자는 플랫폼에 의존)를 지원한다. 어느 형식이나 컴파일된 객체 코드를 포함한다. 스태틱 라이브러리에서는 이 외에 컴파일러 백엔드가 지원하는 중간 표현으로의 출력을 포함할 수도 있으며[193], 에서 이를 이용할 수 있다.

== 코어 라이브러리 ==

코어 라이브러리는 core라는 이름으로 제공된다.[194] 이 라이브러리는 표준 라이브러리에 의존하지 않는 핵심 라이브러리이며, 어떠한 상위 라이브러리, 시스템 라이브러리, libc 라이브러리에도 링크되어 있지 않다. 코어 라이브러리는 최소한의 기능만 제공하며, 힙 할당을 인식하지 않고 병행성이나 입출력도 제공하지 않는다. 이러한 기능들은 플랫폼에 대한 조정이 필요하며, 이 라이브러리는 플랫폼에 의존하지 않는다.

== 표준 라이브러리 ==

`std`라는 이름으로 표준 라이브러리가 제공된다.[195] 이 라이브러리는 `Vec`나 `Option`와 같은 기본적인 자료형, 언어의 기본 처리, 표준 매크로, 입출력(I/O), 멀티스레딩 등의 기능을 제공한다. 표준 라이브러리는 기본적으로 소프트웨어 빌드 시 링크되지만, 보다 근본적인 소프트웨어 또는 리소스가 작은 임베디드 환경에서는 링크를 해제하고 소프트웨어를 빌드할 수 있다.

러스트 표준 라이브러리는 `Vec`, `Option`, `HashMap`과 같은 핵심 자료 구조는 물론 스마트 포인터 유형을 포함하여 널리 사용되는 많은 사용자 정의 데이터 유형을 정의하고 구현한다. 러스트는 또한 `#![no_std]` 속성을 사용하여 표준 라이브러리의 대부분을 제외하는 방법을 제공한다. 이를 통해 종속 코드 제거 또는 자체 핵심 데이터 구조 제공을 원하는 임베디드 장치와 같은 응용 프로그램이 가능하다. 내부적으로 표준 라이브러리는 `core`, `alloc`, `std`의 세 부분으로 나뉘며, 여기서 `std`와 `alloc`는 `#![no_std]`에 의해 제외된다.

`Option` 값은 내부 값(이 경우 문자열)에 접근하기 위해 `if let` 구문과 같은 구문 설탕을 사용하여 처리된다.

러스트 표준 라이브러리의 타입 요약
타입설명예시
`String`UTF-8로 인코딩된 문자열(동적)
플랫폼 네이티브 문자열[36] (빌림[37] 및 동적[38])
경로 (빌림[39] 및 동적[40])
C 호환, 널 종료 문자열 (빌림[41] 및 동적[41])
`Vec`동적 배열
`Option`Option 타입
`Result`예외 처리를 위한 결과 타입을 사용
`Box`힙에 할당된 값에 대한 포인터.[42] C++의 [https://en.cppreference.com/w/cpp/memory/unique_ptr std::unique_ptr]와 유사.
`Rc`참조 카운팅 포인터[43]
`Arc`원자적, 스레드 안전 참조 카운팅 포인터[44]
`Cell`변경 가능한 메모리 위치[45]
`Mutex`내부에 포함된 공유 데이터에 대한 뮤텍스 락[46]
`RwLock`읽기-쓰기 락[47]
`Condvar`공유 데이터에 대한 조건 모니터[48]
`Duration`시간의 범위를 나타내는 타입[49]
`HashMap`해시 테이블[50]
`BTreeMap`B-트리[51]



== 외부 라이브러리 ==

러스트는 기본적인 기능과 범용적인 기능을 포함하여 표준 라이브러리가 아닌 외부 라이브러리로 제공한다. 이는 소위 "배터리 포함(Battery Included)"의 반대되는 것으로, 언어와 함께 업데이트되어 보수적이 되기 쉬운 표준 라이브러리가 아닌, 언어와 독립적으로 업데이트되어 최선을 반복적으로 탐구할 수 있는 외부 라이브러리를 통해 해당 기능을 더 나은 품질로 제공하려는 생각에 기반한다[196]. 외부 라이브러리의 편의성과 품질을 보장하기 위해 https://crates.io crates.iohttps://rust-lang-nursery.github.io/api-guidelines/ API 가이드라인을 제공한다.

언어 개발 커뮤니티가 이에 관여하지 않는 것은 아니며, 기본적인 외부 라이브러리는 커뮤니티 산하에서 개발이 진행되고 있다.

4. 6. 1. 코어 라이브러리

코어 라이브러리는 core라는 이름으로 제공된다.[194] 이 라이브러리는 표준 라이브러리에 의존하지 않는 핵심 라이브러리이며, 어떠한 상위 라이브러리, 시스템 라이브러리, libc 라이브러리에도 링크되어 있지 않다. 코어 라이브러리는 최소한의 기능만 제공하며, 힙 할당을 인식하지 않고 병행성이나 입출력도 제공하지 않는다. 이러한 기능들은 플랫폼에 대한 조정이 필요하며, 이 라이브러리는 플랫폼에 의존하지 않는다.

4. 6. 2. 표준 라이브러리

`std`라는 이름으로 표준 라이브러리가 제공된다.[195] 이 라이브러리는 `Vec`나 `Option`와 같은 기본적인 자료형, 언어의 기본 처리, 표준 매크로, 입출력(I/O), 멀티스레딩 등의 기능을 제공한다. 표준 라이브러리는 기본적으로 소프트웨어 빌드 시 링크되지만, 보다 근본적인 소프트웨어 또는 리소스가 작은 임베디드 환경에서는 링크를 해제하고 소프트웨어를 빌드할 수 있다.

러스트 표준 라이브러리는 `Vec`, `Option`, `HashMap`과 같은 핵심 자료 구조는 물론 스마트 포인터 유형을 포함하여 널리 사용되는 많은 사용자 정의 데이터 유형을 정의하고 구현한다. 러스트는 또한 `#![no_std]` 속성을 사용하여 표준 라이브러리의 대부분을 제외하는 방법을 제공한다. 이를 통해 종속 코드 제거 또는 자체 핵심 데이터 구조 제공을 원하는 임베디드 장치와 같은 응용 프로그램이 가능하다. 내부적으로 표준 라이브러리는 `core`, `alloc`, `std`의 세 부분으로 나뉘며, 여기서 `std`와 `alloc`는 `#![no_std]`에 의해 제외된다.

`Option` 값은 내부 값(이 경우 문자열)에 접근하기 위해 `if let` 구문과 같은 구문 설탕을 사용하여 처리된다.

러스트 표준 라이브러리의 타입 요약
타입설명예시
`String`UTF-8로 인코딩된 문자열(동적)
플랫폼 네이티브 문자열[36] (빌림[37] 및 동적[38])
경로 (빌림[39] 및 동적[40])
C 호환, 널 종료 문자열 (빌림[41] 및 동적[41])
`Vec`동적 배열
`Option`Option 타입
`Result`예외 처리를 위한 결과 타입을 사용
`Box`힙에 할당된 값에 대한 포인터.[42] C++의 [https://en.cppreference.com/w/cpp/memory/unique_ptr std::unique_ptr]와 유사.
`Rc`참조 카운팅 포인터[43]
`Arc`원자적, 스레드 안전 참조 카운팅 포인터[44]
`Cell`변경 가능한 메모리 위치[45]
`Mutex`내부에 포함된 공유 데이터에 대한 뮤텍스 락[46]
`RwLock`읽기-쓰기 락[47]
`Condvar`공유 데이터에 대한 조건 모니터[48]
`Duration`시간의 범위를 나타내는 타입[49]
`HashMap`해시 테이블[50]
`BTreeMap`B-트리[51]


4. 6. 3. 외부 라이브러리

러스트는 기본적인 기능과 범용적인 기능을 포함하여 표준 라이브러리가 아닌 외부 라이브러리로 제공한다. 이는 소위 "배터리 포함(Battery Included)"의 반대되는 것으로, 언어와 함께 업데이트되어 보수적이 되기 쉬운 표준 라이브러리가 아닌, 언어와 독립적으로 업데이트되어 최선을 반복적으로 탐구할 수 있는 외부 라이브러리를 통해 해당 기능을 더 나은 품질로 제공하려는 생각에 기반한다[196]. 외부 라이브러리의 편의성과 품질을 보장하기 위해 https://crates.io crates.iohttps://rust-lang-nursery.github.io/api-guidelines/ API 가이드라인을 제공한다.

언어 개발 커뮤니티가 이에 관여하지 않는 것은 아니며, 기본적인 외부 라이브러리는 커뮤니티 산하에서 개발이 진행되고 있다.

5. 개발 도구

wikitext

Cargo로 러스트 프로그램을 컴파일


러스트 생태계는 컴파일러, 표준 라이브러리, 그리고 소프트웨어 개발을 위한 추가 구성 요소들을 포함한다. 구성 요소 설치는 일반적으로 러스트 프로젝트에서 개발한 러스트 툴체인 설치 관리자인 `rustup`에 의해 관리된다.

러스트(프로그래밍 언어)의 개발 도구는 독립된 소프트웨어로 제공되지만, 러스트의 공식 설치 방법에 따르면 다음 도구들을 함께 사용할 수 있다.

==== rustc ====

`rustc`는 러스트 코드를 로우 레벨 LLVM IR로 변환하는 러스트 컴파일러이다.[77] LLVM은 하위 구성 요소로 호출되어 최적화를 적용하고 결과 IR을 오브젝트 코드로 변환하며, 링커를 사용하여 오브젝트들을 단일 실행 이미지 또는 바이너리 파일로 결합한다.[77]

LLVM 외에도 컴파일러는 코드 생성을 위해 GCC 및 크레인리프트와 같은 대안적인 백엔드를 사용할 수 있다.[78] 이러한 대체 백엔드의 의도는 러스트의 플랫폼 범위를 늘리거나 컴파일 시간을 개선하는 것이다.[79][80]

`rustc`는 Rust로 작성된 Rust 소스 코드를 컴파일하여 중간 코드, 실행 파일, 정적 라이브러리, 동적 라이브러리를 출력한다.[202] 크로스 컴파일을 지원하여 Windows, 리눅스, macOS용 실행 파일 외에 Android나 iOS에서 동작하는 라이브러리를 호스트 머신에서 출력할 수 있다.[203]

대상 플랫폼은 완성도에 따라 3개의 Tier(티어)로 나뉜다.[204] Tier 1은 바이너리 릴리스가 제공되며, 자동 빌드와 자동 테스트가 정비되어 있으며, 이들이 안정적으로 성공(패스)하는 것이 보장된다. Tier 2는 바이너리 릴리스가 제공되며, 자동 빌드와 자동 테스트는 정비되어 있지만 테스트가 성공하는 것은 보장되지 않는다. Tier 3은 소스 코드로는 대응하지만, 자동 빌드와 자동 테스트의 동작이 보장되지 않으며, 공식 릴리스는 제공되지 않는다.

Windows, 리눅스, macOS용 Rust 컴파일러는 티어 1로 릴리스된다. Android, iOS, WebAssembly용 Rust 컴파일러는 티어 2로 릴리스된다.

Rust 1.12 버전부터 도입된 MIR (Mid-level IR)[205] 에 의해, 컴파일과 실행 시간의 신속화 및 타입 검사의 정확성 실현이 도모되고 있다.

==== Cargo ====

카고(cargo)는 러스트빌드 시스템이자 패키지 관리자이다.[288][289] 러스트는 CPU 병행처리 및 메모리 자원 누수 방지 등의 언어 철학 바탕 위에 설계되었으며, 안전하게 제작된 프로그램은 빌드 과정에서 불안정한 결과를 방지할 수 있다는 빌드 시스템으로까지 이어지는 완전한 안정성을 실현하고 있다.

카고는 공식 레지스트리인 "crates.io"에서 관리되는 패키지("크레이트(crate)")를 다운로드, 컴파일, 배포 및 업로드한다.[81] 클리피(Clippy)와 같은 다른 러스트 구성 요소의 프런트 엔드 역할도 수행한다.[81]

기본적으로 카고는 사용자 기여 레지스트리인 "crates.io"에서 종속성을 가져오지만, 깃(Git) 저장소 및 로컬 파일 시스템의 크레이트, 그리고 기타 외부 소스도 종속성으로 지정할 수 있다.[82]

Cargo는 Rust로 작성된 소프트웨어 프로젝트를 위한 명령줄 인터페이스(CLI) 빌드 도구이며, 표준 파일 구조를 가진 프로젝트 디렉토리에서 사용된다.[207] 프로젝트의 빌드(컴파일), 의존 라이브러리 다운로드, 테스트, 문서 생성을 지원하며,[207] 일반적으로 Cargo를 중심으로 개발할 수 있도록 설계되었기 때문에 rustc 컴파일러를 직접 호출하는 경우는 드물다. Cargo가 의존 라이브러리를 다운로드하는 곳은 [https://crates.io/ crates.io]이다.[208]

서브 커맨드는 확장 가능하며, README.md 파일을 자동 생성하는 커맨드[209]와 같은 확장 커맨드가 존재한다. 이러한 확장은 cargo-xxx로 명명된 커맨드를 설치하면 cargo에 xxx라는 서브 커맨드를 추가할 수 있다.

==== rustup ====

`rustup`은 툴체인 관리 소프트웨어이다.[210][211] 툴체인 다운로드 및 설치, 소프트웨어 버전 관리, 컴파일 대상 전환 기능을 제공한다.[210][211]

`rustup`은 Rust 프로젝트가 릴리스하는 컴파일러(`rustc`), 빌드 도구(Cargo) 등의 툴체인을 인터넷을 통해 호스트 머신에 다운로드, 설치 및 관리하는 기능을 제공한다. 설치 대상 툴체인의 버전은 안정 버전, 베타 버전, 나이틀리 버전을 모두 포함하며, 사용자가 필요로 하는 버전을 지정하여 다운로드할 수 있다. 또한, 타겟 플랫폼에 대해서도 모든 종류를 포함하며, 호스트 머신과 다른 플랫폼 (예를 들어, 호스트가 macOS여도 Windows나 Android, iOS)의 컴파일러를 설치할 수 있다. 이 경우, 컴파일러는 크로스 컴파일러로 동작하여 타겟 플랫폼에 맞춘 빌드를 수행한다.

5. 1. rustc

`rustc`는 러스트 코드를 로우 레벨 LLVM IR로 변환하는 러스트 컴파일러이다.[77] LLVM은 하위 구성 요소로 호출되어 최적화를 적용하고 결과 IR을 오브젝트 코드로 변환하며, 링커를 사용하여 오브젝트들을 단일 실행 이미지 또는 바이너리 파일로 결합한다.[77]

LLVM 외에도 컴파일러는 코드 생성을 위해 GCC 및 크레인리프트와 같은 대안적인 백엔드를 사용할 수 있다.[78] 이러한 대체 백엔드의 의도는 러스트의 플랫폼 범위를 늘리거나 컴파일 시간을 개선하는 것이다.[79][80]

`rustc`는 Rust로 작성된 Rust 소스 코드를 컴파일하여 중간 코드, 실행 파일, 정적 라이브러리, 동적 라이브러리를 출력한다.[202] 크로스 컴파일을 지원하여 Windows, 리눅스, macOS용 실행 파일 외에 Android나 iOS에서 동작하는 라이브러리를 호스트 머신에서 출력할 수 있다.[203]

대상 플랫폼은 완성도에 따라 3개의 Tier(티어)로 나뉜다.[204] Tier 1은 바이너리 릴리스가 제공되며, 자동 빌드와 자동 테스트가 정비되어 있으며, 이들이 안정적으로 성공(패스)하는 것이 보장된다. Tier 2는 바이너리 릴리스가 제공되며, 자동 빌드와 자동 테스트는 정비되어 있지만 테스트가 성공하는 것은 보장되지 않는다. Tier 3은 소스 코드로는 대응하지만, 자동 빌드와 자동 테스트의 동작이 보장되지 않으며, 공식 릴리스는 제공되지 않는다.

Windows, 리눅스, macOS용 Rust 컴파일러는 티어 1로 릴리스된다. Android, iOS, WebAssembly용 Rust 컴파일러는 티어 2로 릴리스된다.

Rust 1.12 버전부터 도입된 MIR (Mid-level IR)[205] 에 의해, 컴파일과 실행 시간의 신속화 및 타입 검사의 정확성 실현이 도모되고 있다.

5. 2. Cargo

카고(cargo)는 러스트빌드 시스템이자 패키지 관리자이다.[288][289] 러스트는 CPU 병행처리 및 메모리 자원 누수 방지 등의 언어 철학 바탕 위에 설계되었으며, 안전하게 제작된 프로그램은 빌드 과정에서 불안정한 결과를 방지할 수 있다는 빌드 시스템으로까지 이어지는 완전한 안정성을 실현하고 있다.

카고는 공식 레지스트리인 "crates.io"에서 관리되는 패키지("크레이트(crate)")를 다운로드, 컴파일, 배포 및 업로드한다.[81] 클리피(Clippy)와 같은 다른 러스트 구성 요소의 프런트 엔드 역할도 수행한다.[81]

기본적으로 카고는 사용자 기여 레지스트리인 "crates.io"에서 종속성을 가져오지만, 깃(Git) 저장소 및 로컬 파일 시스템의 크레이트, 그리고 기타 외부 소스도 종속성으로 지정할 수 있다.[82]

Cargo는 Rust로 작성된 소프트웨어 프로젝트를 위한 명령줄 인터페이스(CLI) 빌드 도구이며, 표준 파일 구조를 가진 프로젝트 디렉토리에서 사용된다.[207] 프로젝트의 빌드(컴파일), 의존 라이브러리 다운로드, 테스트, 문서 생성을 지원하며,[207] 일반적으로 Cargo를 중심으로 개발할 수 있도록 설계되었기 때문에 rustc 컴파일러를 직접 호출하는 경우는 드물다. Cargo가 의존 라이브러리를 다운로드하는 곳은 [https://crates.io/ crates.io]이다.[208]

서브 커맨드는 확장 가능하며, README.md 파일을 자동 생성하는 커맨드[209]와 같은 확장 커맨드가 존재한다. 이러한 확장은 cargo-xxx로 명명된 커맨드를 설치하면 cargo에 xxx라는 서브 커맨드를 추가할 수 있다.

5. 3. rustup

`rustup`은 툴체인 관리 소프트웨어이다.[210][211] 툴체인 다운로드 및 설치, 소프트웨어 버전 관리, 컴파일 대상 전환 기능을 제공한다.[210][211]

`rustup`은 Rust 프로젝트가 릴리스하는 컴파일러(`rustc`), 빌드 도구(Cargo) 등의 툴체인을 인터넷을 통해 호스트 머신에 다운로드, 설치 및 관리하는 기능을 제공한다. 설치 대상 툴체인의 버전은 안정 버전, 베타 버전, 나이틀리 버전을 모두 포함하며, 사용자가 필요로 하는 버전을 지정하여 다운로드할 수 있다. 또한, 타겟 플랫폼에 대해서도 모든 종류를 포함하며, 호스트 머신과 다른 플랫폼 (예를 들어, 호스트가 macOS여도 Windows나 Android, iOS)의 컴파일러를 설치할 수 있다. 이 경우, 컴파일러는 크로스 컴파일러로 동작하여 타겟 플랫폼에 맞춘 빌드를 수행한다.

6. 성능

러스트는 C 및 C++와 동등한 수준의 런타임 속도 성능을 가지며[223][224], 일부 처리에서는 C를 능가하는 속도가 확인되고 있다.[225] 메모리 안전성 보장은 런타임 오버헤드를 부과하지 않는다. 주목할 만한 예외는 런타임에 검사되는 배열 인덱싱이지만, 이는 종종 성능에 영향을 미치지 않는다.[86] 가비지 컬렉션을 수행하지 않기 때문에, 러스트는 다른 메모리 안전 언어보다 종종 더 빠르다.[87][53][88]

러스트의 많은 기능은 ''제로 코스트 추상화''로, 컴파일 시간에 최적화되어 런타임에 페널티가 없다. 소유권 및 차용 시스템은 제로 카피 구현을 허용하여 파싱과 같은 일부 성능에 민감한 작업에 활용된다.[90] 정적 디스패치는 동적 트레이트 객체에서 호출되는 메서드를 제외하고, 메서드 호출을 제거하기 위해 기본적으로 사용된다. 컴파일러는 인라인 확장을 사용하여 함수 호출과 정적으로 디스패치된 메서드 호출을 제거한다.[91]

러스트는 LLVM을 활용하기 때문에 LLVM의 모든 성능 향상은 러스트에도 적용된다.[92] C 및 C++와 달리, 러스트는 메모리 내 구조체의 크기를 줄이고 메모리 정렬을 개선하며 캐시 접근 효율성을 높이기 위해 구조체 및 열거형 요소를 재정렬할 수 있다.[94]

2018년 2월 시점에서, 웹 서버 애플리케이션의 범용 처리에서는 속도 성능이 좋은 Rust 기반 라이브러리 개발이 진행되지 않았다.[226] 단순한 텍스트 처리에서는 속도 성능이 좋다.[227]

7. 채택 사례

모질라의 파이어폭스 웹 브라우저[291]게코 브라우저 엔진의 일부로 러스트로 작성된 구성 요소를 가지고 있으며, 삼성과 함께 개발하는 병렬 렌더링 엔진 서보[293][294]의 구성 요소는 파이어폭스에 통합되었다.[95] 구글 (알파벳)은 2023년 1월 크로미움에서 타사 러스트 라이브러리 사용 지원을 발표했다.[96][97]

파이어폭스


리눅스용 러스트


대규모 웹 서비스의 여러 백엔드 소프트웨어 프로젝트에서 러스트가 사용된다. 시스코(Cisco)가 소유한 DNS 서비스인 오픈DNS는 내부적으로 러스트를 사용하며[98][99], 구성 요소 중 2개에 러스트를 사용하고 있다.[295][296][297] 아마존 웹 서비스(Amazon Web Services)는 여러 서비스의 "성능에 민감한 구성 요소"에 러스트를 사용하며, 2019년에는 주로 러스트로 작성된 가상화 솔루션인 파이어크래커를 오픈 소스로 공개했다.[100] 마이크로소프트 애저 IoT Edge는 IoT 장치에서 애저 서비스를 실행하는 데 사용되는 플랫폼으로, 러스트로 구현된 구성 요소를 가지고 있다.[101] 마이크로소프트는 WebAssembly 및 쿠버네티스를 사용하여 컨테이너화된 모듈을 실행하는 데에도 러스트를 사용한다.[102] 클라우드플레어(Cloudflare)는 콘텐츠 전송 네트워크 서비스를 제공하며, 성능과 효율성을 높이기 위해 Pingora라는 새로운 웹 프록시를 구축하는 데 러스트를 사용했다.[103] npm 패키지 관리자는 2019년에 프로덕션 인증 서비스에 러스트를 사용했다.[104][105][106]

운영 체제 분야에서는 2020년에 시작된 리눅스용 러스트 프로젝트가 2022년 말 리눅스 커널 버전 6.1에 초기 지원을 통합했다.[107][108] 러스트로 작성된 최초의 드라이버는 버전 6.8 커널에 통합되었다.[107] 안드로이드 개발자는 2021년에 기존 구성 요소를 다시 작성하기 위해 러스트를 사용했다.[111][112] 마이크로소프트는 윈도우의 일부를 러스트로 다시 작성했다.[113] 레독스[115]와 같은 새로운 운영 체제 개발에도 사용되었다.[298]

웹 개발 분야에서는 자바스크립트와 타입스크립트를 위한 안전한 런타임인 데노가 러스트와 Tokio를 사용하여 V8 위에 구축되었다.[122] 디스코드는 인스턴트 메시징 소프트웨어 회사로, 2020년에 성능 향상을 위해 시스템의 일부를 러스트로 다시 작성했다. 같은 해에 드롭박스는 파일 동기화가 러스트로 다시 작성되었다고 발표했다.

이외에도 드롭박스의 파일 스토리지 시스템인 매직 포켓,[292] 분산 키 값 데이터베이스인 TiKV,[299] 모듈식 게임 엔진 Piston,[300] 블록체인 오픈 소스 프레임워크 Exonum,[268] TLS의 Rust 구현 rustls,[273] 버전 관리 시스템 Pijul,[275] 텍스트 편집기 Xi,[276] grep에 해당하는 고속 텍스트 검색 도구 ripgrep,[277] AV1 인코더 구현 rav1e,[278] 서로 다른 블록체인 간의 상호 운용성을 실현하는 오픈 소스 프로토콜 Polkadot,[279] 어도비 플래시 플레이어의 대체재로 개발 중인 에뮬레이터 러플[123] 등 다양한 프로젝트가 러스트로 개발되거나 개발에 사용되고 있다.

7. 1. 웹 브라우저

모질라와 삼성이 개발에 참여한 서보 브라우저 엔진의 구성 요소는 파이어폭스의 게코 브라우저 엔진에 통합되었다.[95]

2023년 1월, 구글은 크로미움에서 타사 러스트 라이브러리 사용 지원을 발표했다.[96][97]

7. 2. 운영 체제

리눅스용 러스트 프로젝트는 2020년에 시작되어 2022년 말 리눅스 커널 버전 6.1에 초기 지원이 통합되었다.[107][108] 6-7명의 개발자 팀이 2022년부터 2024년까지 커널 릴리스에 추가적인 러스트 코드를 추가하여[109] 프로젝트의 최소 실행 가능성을 입증하고 주요 호환성 문제를 해결하는 것을 목표로 하고 있다.[107][110] 러스트로 작성된 최초의 드라이버는 버전 6.8 커널에 통합되었다.[107]

안드로이드 개발자는 2021년에 기존 구성 요소를 다시 작성하기 위해 러스트를 사용했다.[111][112] 마이크로소프트는 윈도우의 일부를 러스트로 다시 작성했다.[113] r9 프로젝트는 벨 연구소의 플랜 9를 러스트로 다시 구현하는 것을 목표로 한다.[114]

러스트는 "유닉스 계열" 운영 체제이자 마이크로커널인 레독스와[115] 모듈식 상태 관리를 갖춘 실험적인 운영 체제인 Theseus,[116][117] 그리고 퓨시아의 대부분과 같은 새로운 운영 체제 개발에 사용되었다.[118] 파일 시스템 관리자인 stratisd[119][120] 및 System76의 데스크톱 환경인 COSMIC을 포함한 명령줄 도구 및 운영 체제 구성 요소에도 사용된다.[121]

7. 3. 기타

러스트는 다양한 분야의 소프트웨어 개발에 사용되고 있다. 모질라의 파이어폭스 웹 브라우저[291]게코 브라우저 엔진의 일부로 러스트로 작성된 구성 요소를 가지고 있으며, 삼성과 함께 개발하는 병렬 렌더링 엔진 서보[293][294]의 구성 요소는 파이어폭스에 통합되었다.[95] 구글 (알파벳)은 2023년 1월 크로미움에서 타사 러스트 라이브러리 사용 지원을 발표했다.[96][97]

대규모 웹 서비스의 여러 백엔드 소프트웨어 프로젝트에서 러스트가 사용된다. 시스코(Cisco)가 소유한 DNS 서비스인 오픈DNS는 내부적으로 러스트를 사용하며[98][99], 구성 요소 중 2개에 러스트를 사용하고 있다.[295][296][297] 아마존 웹 서비스(Amazon Web Services)는 여러 서비스의 "성능에 민감한 구성 요소"에 러스트를 사용하며, 2019년에는 주로 러스트로 작성된 가상화 솔루션인 파이어크래커를 오픈 소스로 공개했다.[100] 마이크로소프트 애저 IoT Edge는 IoT 장치에서 애저 서비스를 실행하는 데 사용되는 플랫폼으로, 러스트로 구현된 구성 요소를 가지고 있다.[101] 마이크로소프트는 WebAssembly 및 쿠버네티스를 사용하여 컨테이너화된 모듈을 실행하는 데에도 러스트를 사용한다.[102] 클라우드플레어(Cloudflare)는 콘텐츠 전송 네트워크 서비스를 제공하며, 성능과 효율성을 높이기 위해 Pingora라는 새로운 웹 프록시를 구축하는 데 러스트를 사용했다.[103] npm 패키지 관리자는 2019년에 프로덕션 인증 서비스에 러스트를 사용했다.[104][105][106]

운영 체제 분야에서는 2020년에 시작된 리눅스용 러스트 프로젝트가 2022년 말 리눅스 커널 버전 6.1에 초기 지원을 통합했다.[107][108] 러스트로 작성된 최초의 드라이버는 버전 6.8 커널에 통합되었다.[107] 안드로이드 개발자는 2021년에 기존 구성 요소를 다시 작성하기 위해 러스트를 사용했다.[111][112] 마이크로소프트는 윈도우의 일부를 러스트로 다시 작성했다.[113] 레독스[115]와 같은 새로운 운영 체제 개발에도 사용되었다.[298]

웹 개발 분야에서는 자바스크립트와 타입스크립트를 위한 안전한 런타임인 데노가 러스트와 Tokio를 사용하여 V8 위에 구축되었다.[122] 디스코드는 인스턴트 메시징 소프트웨어 회사로, 2020년에 성능 향상을 위해 시스템의 일부를 러스트로 다시 작성했다. 같은 해에 드롭박스는 파일 동기화가 러스트로 다시 작성되었다고 발표했다.

이외에도 드롭박스의 파일 스토리지 시스템인 매직 포켓,[292] 분산 키 값 데이터베이스인 TiKV,[299] 모듈식 게임 엔진 Piston,[300] 블록체인 오픈 소스 프레임워크 Exonum,[268] TLS의 Rust 구현 rustls,[273] 버전 관리 시스템 Pijul,[275] 텍스트 편집기 Xi,[276] grep에 해당하는 고속 텍스트 검색 도구 ripgrep,[277] AV1 인코더 구현 rav1e,[278] 서로 다른 블록체인 간의 상호 운용성을 실현하는 오픈 소스 프로토콜 Polkadot,[279] 어도비 플래시 플레이어의 대체재로 개발 중인 에뮬레이터 러플[123] 등 다양한 프로젝트가 러스트로 개발되거나 개발에 사용되고 있다.

8. 평가

Stack Overflow 개발자 설문조사에서 2016년부터 2022년까지 "가장 사랑받는 프로그래밍 언어" 1위를 계속 차지하여[216] 프로그래머들의 호의적인 평가가 많다.

한편으로는, 러스트는 학습 난이도가 높은 언어라고 여겨지기도 한다[217]. 컴파일러(borrow checker, 차용 검사기)가 오류를 감지하여 발생하는 "차용 검사기와의 싸움"이 잦고[218][219], Go 언어와 비교했을 때 개발 효율이 낮다는 평가도 있다[220]. 러스트 개발팀은 이러한 학습 난이도 문제를 인지하고, 2017년 로드맵에서 학습 곡선 개선을 목표로 설정하였다[221][222].

이러한 문제 개선을 위해 자동화를 위한 개발 및 도구 정비, 하위 호환성 유지, 라이브러리 생태계 확장에 힘쓰고 있다.

러스트의 런타임 속도 성능은 LLVM을 사용하는 C 언어와 동등한 수준이며[223][224], 일부 처리에서는 C 언어를 능가한다[225]. 2018년 2월에는 웹 서버 애플리케이션의 범용 처리에서 속도 성능이 좋은 Rust 기반 라이브러리 개발이 미진했으나[226], 단순 텍스트 처리에서는 우수한 성능을 보인다[227]. 이후 벤치마크에서는 병렬 처리 및 그래픽 처리에서도 Java나 Go를 능가하는 성능을 보여주었다.

참조

[1] 웹사이트 Platform Support https://doc.rust-lan[...] 2022-06-27
[2] 웹사이트 The Rust Programming Language https://github.com/r[...] The Rust Programming Language 2022-10-19
[3] 웹사이트 Uniqueness Types https://blog.rust-la[...] 2016-10-08
[4] 웹사이트 Uniqueness Types http://docs.idris-la[...] 2022-07-14
[5] 웹사이트 V documentation (Introduction) https://github.com/v[...] 2023-11-04
[6] 웹사이트 New challenger joins Rust to topple C language https://www.infoworl[...] 2022-10-19
[7] 서적 Practical System Programming for Rust Developers: Build fast and secure software for Linux/Unix systems with the help of practical examples https://books.google[...] Packt Publishing Ltd 2020-12-24
[8] 간행물 What can the programming language Rust do for astrophysics? https://www.cambridg[...] 2017-05-30
[9] 뉴스 Rust takes a major step forward as Linux's second official language https://www.zdnet.co[...] 2024-11-27
[10] 웹사이트 How Rust went from a side project to the world's most-loved programming language https://www.technolo[...] 2023-02-23
[11] 서적 Applicative 2016 on - Applicative 2016 Association for Computing Machinery 2016-06-02
[12] 컨퍼런스 Project Servo: Technology from the past come to save the future from itself http://venge.net/gra[...] Mozilla Annual Summit 2024-10-29
[13] 웹사이트 Rust Prehistory (Archive of the original Rust OCaml compiler source code) https://github.com/g[...] 2024-10-29
[14] 웹사이트 0.1 first supported public release Milestone · rust-lang/rust https://github.com/r[...] 2024-10-29
[15] AV media RustConf 2022 - Bootstrapping: The once and future compiler https://www.youtube.[...] Rust Team 2024-10-29
[16] 웹사이트 Rust logo https://bugzilla.moz[...] 2024-02-02
[17] 웹사이트 Purity by pcwalton · Pull Request #5412 · rust-lang/rust https://github.com/r[...] 2024-10-29
[18] 뉴스 The Rise And Fall of Languages in 2013 https://www.drdobbs.[...] 2022-11-20
[19] 뉴스 Mozilla And Samsung Team Up To Develop Servo, Mozilla's Next-Gen Browser Engine For Multicore Processors https://techcrunch.c[...] 2017-06-25
[20] 웹사이트 Firefox 45.0, See All New Features, Updates and Fixes https://www.mozilla.[...] 2024-10-31
[21] 웹사이트 It's time to give Firefox another chance https://techcrunch.c[...] 2023-08-15
[22] 서적 Proceedings of the 10th ACM SIGPLAN International Conference on Software Language Engineering Association for Computing Machinery 2017-10-23
[23] 웹사이트 Mozilla lays off 250 employees while it refocuses on commercial products https://www.zdnet.co[...] ZDNet 2020-08-11
[24] 웹사이트 Mozilla lays off 250 employees due to the pandemic https://www.engadget[...] 2020-08-11
[25] 웹사이트 Programming language Rust: Mozilla job cuts have hit us badly but here's how we'll survive https://www.zdnet.co[...] ZDNet 2022-04-21
[26] 웹사이트 Laying the foundation for Rust's future https://blog.rust-la[...] 2020-08-18
[27] 웹사이트 Hello World! https://foundation.r[...] 2022-06-04
[28] 웹사이트 Mozilla Welcomes the Rust Foundation https://blog.mozilla[...] 2021-02-09
[29] 웹사이트 Google is now writing low-level Android code in Rust https://arstechnica.[...] 2021-04-08
[30] 뉴스 Entire Rust moderation team resigns https://www.theregis[...] 2022-08-04
[31] 웹사이트 Governance Update https://blog.rust-la[...] 2022-10-27
[32] 뉴스 Rust Foundation apologizes for trademark policy confusion https://www.theregis[...] 2023-05-07
[33] 뉴스 Rebecca Rumbul named new CEO of The Rust Foundation https://www.theregis[...] 2022-07-14
[34] 웹사이트 Rust programming for Java developers https://www.infoworl[...] 2022-07-14
[35] 웹사이트 Glossary of Unicode Terms https://www.unicode.[...] 2024-07-30
[36] 문서 On Unix systems, this is often UTF-8 strings without an internal 0 byte. On Windows, this is [[UTF-16]] strings without an internal 0 byte. Unlike these,
[37] 웹사이트 OsStr in std::ffi – Rust https://doc.rust-lan[...] 2023-10-02
[38] 웹사이트 OsString in std::ffi – Rust https://doc.rust-lan[...] 2023-10-02
[39] 웹사이트 Path in std::path – Rust https://doc.rust-lan[...] 2023-10-02
[40] 웹사이트 PathBuf in std::path – Rust https://doc.rust-lan[...] 2023-10-02
[41] 웹사이트 std::boxed – Rust https://doc.rust-lan[...] 2023-06-23
[42] 웹사이트 std::boxed – Rust https://doc.rust-lan[...] 2023-06-24
[43] 웹사이트 Rc in std::rc – Rust https://doc.rust-lan[...] 2023-06-24
[44] 웹사이트 Arc in std::sync – Rust https://doc.rust-lan[...] 2023-06-24
[45] 웹사이트 Cell in std::cell – Rust https://doc.rust-lan[...] 2023-06-24
[46] 웹사이트 Mutex in std::sync – Rust https://doc.rust-lan[...] 2023-06-24
[47] 웹사이트 RwLock in std::sync – Rust https://doc.rust-lan[...] 2023-06-24
[48] 웹사이트 Condvar in std::sync – Rust https://doc.rust-lan[...] 2023-06-24
[49] 웹사이트 Duration in std::time – Rust https://doc.rust-lan[...] 2023-06-24
[50] 웹사이트 HashMap in std::collections – Rust https://doc.rust-lan[...] 2023-06-24
[51] 웹사이트 BTreeMap in std::collections – Rust https://doc.rust-lan[...] 2023-06-24
[52] 웹사이트 std::option - Rust https://doc.rust-lan[...] 2023-11-12
[53] 서적 Proceedings of the 16th Workshop on Hot Topics in Operating Systems Association for Computing Machinery 2022-06-01
[54] 웹사이트 Lifetimes - Rust By Example https://doc.rust-lan[...] 2024-10-29
[55] 웹사이트 Explicit annotation - Rust By Example https://doc.rust-lan[...] 2024-10-29
[56] 웹사이트 The Rust Borrow Checker – a Deep Dive https://www.infoq.co[...] 2022-06-25
[57] 웹사이트 References and Borrowing - The Rust Programming Language https://doc.rust-lan[...] 2024-10-29
[58] 학술저널 A Lightweight Formalism for Reference Lifetimes and Borrowing in Rust https://dl.acm.org/d[...] 2021-04-17
[59] 웹사이트 Using Trait Objects That Allow for Values of Different Types – The Rust Programming Language https://doc.rust-lan[...] 2022-07-11
[60] 웹사이트 Samsung joins Mozilla's quest for Rust http://reviews.cnet.[...] CNET 2013-04-05
[61] 웹사이트 A taste of Rust https://lwn.net/Arti[...] 2013-04-25
[62] 웹사이트 Races – The Rustonomicon https://doc.rust-lan[...] 2017-07-03
[63] 학술저널 Overview of Embedded Rust Operating Systems and Frameworks Sensors_(journal) 2024-09-07
[64] 웹사이트 The Rust Language FAQ http://static.rust-l[...] 2017-04-24
[65] 웹사이트 RAII – Rust By Example https://doc.rust-lan[...] 2020-11-22
[66] 웹사이트 Abstraction without overhead: traits in Rust https://blog.rust-la[...] 2021-10-19
[67] 웹사이트 Box, stack and heap https://doc.rust-lan[...] 2022-06-13
[68] 웹사이트 Macros By Example https://doc.rust-lan[...] 2023-04-21
[69] 웹사이트 Rust std::println! macro source https://github.com/r[...] 2024-10-01
[70] 웹사이트 Procedural Macros https://doc.rust-lan[...] 2021-03-23
[71] 웹사이트 Dioxus rsx! macro source https://github.com/D[...] 2024-10-01
[72] 웹사이트 Dioxus rsx! macro documentation https://dioxuslabs.c[...] 2024-10-01
[73] 웹사이트 Serde Derive https://serde.rs/der[...] 2021-03-23
[74] 웹사이트 extendr_api – Rust https://extendr.gith[...] 2021-03-23
[75] 웹사이트 Safe Interoperability between Rust and C++ with CXX https://www.infoq.co[...] 2020-12-06
[76] 웹사이트 Type layout – The Rust Reference https://doc.rust-lan[...] 2022-07-15
[77] 웹사이트 Overview of the compiler https://rustc-dev-gu[...] Rust project contributors 2024-11-07
[78] 웹사이트 Code Generation - Rust Compiler Development Guide https://rustc-dev-gu[...] 2024-03-03
[79] 웹사이트 rust-lang/rustc_codegen_gcc https://github.com/r[...] The Rust Programming Language 2024-03-02
[80] 웹사이트 rust-lang/rustc_codegen_cranelift https://github.com/r[...] The Rust Programming Language 2024-03-02
[81] 간행물 Why scientists are turning to Rust https://www.nature.c[...] 2020-12-01
[82] 웹사이트 Rust 1.34 Introduces Alternative Registries for Non-Public Crates https://www.infoq.co[...] 2019-04-18
[83] Citation Clippy https://github.com/r[...] The Rust Programming Language 2023-11-30
[84] 웹사이트 Clippy Lints https://rust-lang.gi[...]
[85] 문서 Klabnik Nichols 2019
[86] 간행물 Safer at any speed: automatic context-aware safety enhancement for Rust 2021-10-15
[87] 웹사이트 Can Rust save the planet? Why, and why not https://www.theregis[...]
[88] 웹사이트 What is the Rust language? Safe, fast, and easy software development https://www.infoworl[...] 2021-10-06
[89] 간행물 How do programmers use unsafe rust? https://dl.acm.org/d[...] 2020-11-13
[90] 서적 2015 IEEE Security and Privacy Workshops 2015
[91] 웹사이트 Code generation – The Rust Reference https://doc.rust-lan[...]
[92] 웹사이트 How Fast Is Rust? https://doc.rust-lan[...] 2019-04-11
[93] 서적 Proceedings of the 26th ACM International Conference on Architectural Support for Programming Languages and Operating Systems https://dlnext.acm.o[...]
[94] 웹사이트 Type layout https://doc.rust-lan[...]
[95] 웹사이트 Mozilla plans to rejuvenate Firefox in 2017 https://www.computer[...] 2016-10-31
[96] 웹사이트 Google polishes Chromium code with a layer of Rust https://www.theregis[...] 2023-01-12
[97] 웹사이트 Supporting the Use of Rust in the Chromium Project https://security.goo[...]
[98] 웹사이트 Firefox will get overhaul in bid to get you interested again https://www.cnet.com[...] CNET 2016-07-12
[99] 웹사이트 ZeroMQ: Helping us Block Malicious Domains in Real Time https://umbrella.cis[...] 2013-10-04
[100] 웹사이트 AWS to sponsor Rust project https://www.zdnet.co[...] 2019-10-15
[101] 웹사이트 Microsoft's next trick? Kicking things out of the cloud to Azure IoT Edge https://www.theregis[...] 2018-06-27
[102] 웹사이트 Microsoft: Why we used programming language Rust over Go for WebAssembly on Kubernetes app https://www.zdnet.co[...] ZDNet
[103] 웹사이트 In Rust We Trust: Microsoft Azure CTO shuns C and C++ https://www.theregis[...] 2022-09-20
[104] 웹사이트 NPM Adopted Rust to Remove Performance Bottlenecks https://www.infoq.co[...]
[105] Citation Welcome to the World of Rust https://doi.org/10.1[...] Apress 2020
[106] 간행물 Rust in the Web World https://doi.org/10.1[...] Apress 2023-11-29
[107] 웹사이트 An Empirical Study of Rust-for-Linux: The Success, Dissatisfaction, and Compromise https://www.usenix.o[...] 2024-11-28
[108] 웹사이트 A first look at Rust in the 6.1 kernel [LWN.net] https://lwn.net/Arti[...] 2023-11-11
[109] 웹사이트 Rust in the 6.2 kernel [LWN.net] https://lwn.net/Arti[...] 2024-11-28
[110] 웹사이트 Committing to Rust in the kernel [LWN.net] https://lwn.net/Arti[...] 2024-11-28
[111] 웹사이트 Google is now writing low-level Android code in Rust https://arstechnica.[...] 2022-04-21
[112] 웹사이트 Google Develops New Bluetooth Stack for Android, Written in Rust https://blog.desdeli[...] 2024-08-31
[113] 웹사이트 Microsoft is rewriting core Windows libraries in Rust https://www.theregis[...] 2023-05-13
[114] 웹사이트 Small but mighty, 9Front's 'Humanbiologics' is here for the truly curious https://www.theregis[...] 2024-03-07
[115] 뉴스 Rust's Redox OS could show Linux a few new tricks http://www.infoworld[...] 2016-03-21
[116] 웹사이트 Another Rust-y OS: Theseus joins Redox in pursuit of safer, more resilient systems https://www.theregis[...] 2022-07-14
[117] 서적 Theseus: an Experiment in Operating System Structure and State Management https://www.usenix.o[...] 2020
[118] 웹사이트 '2022 Review {{!}} The adoption of Rust in Business' https://rustmagazine[...] 2023-02-07
[119] 웹사이트 Fedora 29 new features: Startis now officially in Fedora https://www.marksei.[...] 2019-05-13
[120] 웹사이트 Oracle Linux 9 released, with some interesting additions https://www.theregis[...] 2022-07-14
[121] 웹사이트 System76 teases features coming in homegrown Rust-based desktop COSMIC https://www.theregis[...] 2024-07-17
[122] 웹사이트 Deno Is Ready for Production https://www.infoq.co[...] 2022-07-14
[123] 웹사이트 This Flash Player emulator lets you securely play your old games https://www.bleeping[...] 2021-12-25
[124] 웹사이트 Ethereum Blockchain Killer Goes By Unassuming Name of Polkadot https://www.bloomber[...] Bloomberg L.P. 2021-07-14
[125] 웹사이트 2024 Stack Overflow Developer Survey - Technology https://survey.stack[...] 2024-11-28
[126] 웹사이트 Linus Torvalds says Rust is coming to the Linux kernel https://www.theregis[...] 2022-07-15
[127] 논문 RustBelt: securing the foundations of the Rust programming language https://dl.acm.org/d[...] 2017-12-27
[128] 논문 Safer at any speed: automatic context-aware safety enhancement for Rust 2021-10-20
[129] 웹사이트 Getting Started https://www.rust-lan[...] 2020-10-11
[130] 웹사이트 The Rust programming language just took a huge step forwards https://www.zdnet.co[...] ZDNet 2022-07-14
[131] 웹사이트 The Rust programming language now has its own independent foundation https://www.techrepu[...] 2022-07-14
[132] 뉴스 Rust language moves to independent foundation https://www.infoworl[...] 2021-04-10
[133] 뉴스 AWS's Shane Miller to head the newly created Rust Foundation https://www.zdnet.co[...] ZDNet 2021-04-10
[134] 뉴스 Rust Foundation appoints Rebecca Rumbul as executive director https://www.zdnet.co[...] ZDNet 2021-11-18
[135] 웹사이트 Governance https://www.rust-lan[...] 2024-07-18
[136] 웹사이트 Introducing the Rust Leadership Council https://blog.rust-la[...] 2024-01-12
[137] 웹사이트 Rust vs. C++ Comparison https://www.apriorit[...] 2018-11-20
[138] 웹사이트 Fearless Security: Memory Safety https://hacks.mozill[...] 2020-11-04
[139] 웹사이트 Rc, the Reference Counted Smart Pointer https://doc.rust-lan[...] 2020-11-04
[140] 웹사이트 The Rust Community · The Rust Programming Language https://www.rust-lan[...] 2018-02-04
[141] 웹사이트 rust-lang/rust: A safe, concurrent, practical language. https://www.rust-lan[...] github 2018-02-04
[142] 웹사이트 CやC++に代わると期待--安全な並行性とメモリーの安全性に焦点当てる「Rust」 https://japan.zdnet.[...] 2020-02-01
[143] 웹사이트 The Rust Language http://lambda-the-ul[...] Lambda the Ultimate 2010-07-08
[144] 웹사이트 Internet archaeology: the definitive, end-all source for why Rust is named "Rust" https://www.reddit.c[...] 2020-05-10
[145] 웹사이트 Rust logo(type) https://bugzilla.moz[...] Mozilla Foundation 2020-05-10
[146] 웹사이트 The Rust Team · The Rust Programming Language https://www.rust-lan[...] Rust Project Developers 2018-02-04
[147] 웹사이트 The Rust Programming Language https://github.com/r[...] github 2018-02-04
[148] 웹사이트 Contributors to rust-lang/rust https://github.com/r[...] github 2018-01-28
[149] 웹사이트 The Mozilla Manifesto http://www.mozilla.o[...] 2012-04-09
[150] 웹사이트 rust-lang/rfcs: RFCs for changes to Rust https://github.com/r[...] github 2018-02-04
[151] 웹사이트 rust-lang/rfcs: RFCs for changes to Rust https://github.com/r[...] 2018-01-28
[152] 웹사이트 Refining Rust's RFCs https://aturon.githu[...] 2018-01-28
[153] 웹사이트 bindgen 0.17.0 - Docs.rs https://docs.rs/crat[...] Onur Aslan 2018-02-04
[154] 웹사이트 merge into upstream! · Issue #21 · rust-lang-nursery/rust-bindgen https://github.com/r[...] github 2018-02-04
[155] 웹사이트 rust-lang-nursery/rust-bindgen Automatically generates Rust FFI bindings to C (and some C++) libraries. https://github.com/r[...] 2018-02-04
[156] 웹사이트 rust/src/grammar/parser-lalr.y https://github.com/r[...] 2017-05-23
[157] 웹사이트 “Frequently Asked Questions · The Rust Programming Language - When should I use an implicit return? https://www.rust-lan[...] 2018-01-28
[158] 문서 by default variables are immutable. https://doc.rust-lan[...]
[159] 문서 E0384. An immutable variable was reassigned. https://doc.rust-lan[...]
[160] 문서 you can make them mutable by adding mut in front of the variable name. https://doc.rust-lan[...]
[161] 문서 you can declare a new variable with the same name as a previous variable, and the new variable shadows the previous variable. https://doc.rust-lan[...]
[162] 문서 By using let, we can perform a few transformations on a value but have the variable be immutable after those transformations have been completed. ... The other difference between mut and shadowing is that because we’re effectively creating a new variable when we use the let keyword again, we can change the type of the value but reuse the same name. https://doc.rust-lan[...]
[163] 문서 higher-kinded polymorphism
[164] 웹사이트 Type coercions https://doc.rust-lan[...] 2024-03-27
[165] 웹사이트 Rust Features I: Type Inference http://pcwalton.blog[...] 2010-10-01
[166] 문서 monomorphization
[167] 웹사이트 Abstraction without overhead: traits in Rust - The Rust Programming Language Blog https://blog.rust-la[...] 2015-05-11
[168] 문서 A reference represents a borrow of some owned value. https://doc.rust-lan[...]
[169] 문서 A reference ... to access the data stored at that address; that data is owned by some other variable. https://doc.rust-lan[...]
[170] 문서 A reference cannot outlive its referent https://doc.rust-lan[...]
[171] 문서 A lifetime is said to “outlive” another one if its representative scope is as long or longer than the other. https://doc.rust-lan[...]
[172] 문서 The issue ... we have to return the String to the calling function so we can still use ... . Instead, we can provide a reference https://doc.rust-lan[...]
[173] 문서 "'''Syntax''' ''BorrowExpression''" https://doc.rust-lan[...]
[174] 문서 Primitive Type reference ... References, &T and &mut T. https://doc.rust-lan[...]
[175] 문서 Borrow operators https://doc.rust-lan[...]
[176] 웹사이트 "shared reference type is written &type" https://doc.rust-lan[...] 2022-12-24
[177] 웹사이트 "The & (shared borrow) ... operators" https://doc.rust-lan[...] 2022-12-24
[178] 웹사이트 "A mutable reference type is written &mut type" https://doc.rust-lan[...] 2022-12-24
[179] 웹사이트 "&mut (mutable borrow) operators" https://doc.rust-lan[...] 2022-12-24
[180] 웹사이트 "When a shared reference to a value is created, it prevents direct mutation of the value." https://doc.rust-lan[...] 2022-12-24
[181] 웹사이트 "The following traits are implemented for all &T, regardless of the type of its referent: Copy" https://doc.rust-lan[...] 2022-12-24
[182] 웹사이트 "if you have a mutable reference to a value, you can have no other references to that value." https://doc.rust-lan[...] 2022-12-24
[183] 웹사이트 "&mut T references get all of the above except Copy and Clone (to prevent creating multiple simultaneous mutable borrows)" https://doc.rust-lan[...] 2022-12-24
[184] 웹사이트 jemalloc is removed by default https://blog.rust-la[...] 2020-06-12
[185] 웹사이트 Validating References with Lifetimes https://doc.rust-lan[...] 2024-01-02
[186] 웹사이트 Trait and lifetime bounds https://doc.rust-lan[...] 2024-01-02
[187] 웹사이트 Trait and lifetime bounds https://doc.rust-lan[...] 2024-01-02
[188] 웹사이트 Higher-Rank Trait Bounds (HRTBs) https://doc.rust-lan[...] 2024-01-02
[189] 웹사이트 Module std::pin https://doc.rust-lan[...] 2024-01-02
[190] 웹사이트 Module std::pin, Example: self-referential struct https://doc.rust-lan[...] 2024-01-02
[191] 웹사이트 Working with an unpublished minor version https://doc.rust-lan[...] 2018-01-28
[192] 웹사이트 Libraries and Metadata https://rustc-dev-gu[...] 2024-12-11
[193] 웹사이트 Add -Cbitcode-in-rlib. #71323 https://github.com/r[...] 2024-12-11
[194] 웹사이트 core- Rust https://doc.rust-lan[...] 2018-01-28
[195] 웹사이트 std- Rust https://doc.rust-lan[...] 2018-01-28
[196] 웹사이트 The Rust Libz Blitz - The Rust Programming Language Blog https://blog.rust-la[...] 2018-02-04
[197] 웹사이트 rand - Cargo: packages for Rust https://crates.io/cr[...] 2018-01-28
[198] 웹사이트 regex - Cargo: packages for Rust https://crates.io/cr[...] 2018-01-28
[199] 웹사이트 chrono - Cargo: packages for Rust https://crates.io/cr[...] 2018-01-28
[200] 웹사이트 libc - Cargo: packages for Rust https://crates.io/cr[...] 2018-01-28
[201] 웹사이트 log - Cargo: packages for Rust https://crates.io/cr[...] 2018-01-28
[202] 서적 Programming Rust O'Reilly Media, Inc
[203] 웹사이트 Taking Rust everywhere with rustup https://blog.rust-la[...] 2018-01-28
[204] 웹사이트 Rust Platform Support · The Rust Programming Language https://forge.rust-l[...] 2018-02-04
[205] 웹사이트 Introducing MIR https://blog.rust-la[...] 2016-10-04
[206] 웹사이트 Releases · rust-lang/cargo · GitHub https://github.com/r[...]
[207] 웹사이트 Cargo: predictable dependency management - The Rust Programming Language Blog https://blog.rust-la[...] 2018-02-04
[208] 웹사이트 Cargo: Rust's community crate host https://blog.rust-la[...] 2018-01-28
[209] 웹사이트 Cargo-readme: generate README.md from doc comments https://users.rust-l[...] 2018-01-28
[210] 웹사이트 RustUp aka How to install rust the convenient way http://www.shadercat[...] 2018-02-04
[211] 웹사이트 Taking Rust everywhere with rustup - The Rust Programming Language Blog https://blog.rust-la[...] 2016-05-13
[212] 웹사이트 rust/getting-started.md at 1.13.0 · rust-lang/rust https://github.com/r[...] 2016-09-27
[213] 웹사이트 rust-lang-deprecated/rustup.sh: The rustup.sh script for installing Rust from release channels https://github.com/r[...]
[214] 웹사이트 rust/getting-started.md at 1.14.0 · rust-lang/rust https://github.com/r[...] 2016-12-17
[215] 웹사이트 rust-lang-nursery/rustup.rs: The Rust toolchain installer https://github.com/r[...]
[216] 웹사이트 Stack Overflow Developer Survey 2022 https://survey.stack[...] 2022-07-10
[217] 웹사이트 Interview with Steve Klabnik: How Rust Compares to Other Languages and More https://www.codement[...] codementor 2014-10-24
[218] 웹사이트 book/references-and-borrowing.md at master · rust-lang/book https://github.com/r[...] 2017-05-10
[219] 웹사이트 Why Rust's ownership/borrowing is hard https://news.ycombin[...] 2016-11-02
[220] 웹사이트 Go vs Rust? Choose Go. https://matthias-end[...] 2017-09-15
[221] 웹사이트 Rust's 2017 roadmap https://blog.rust-la[...]
[222] 웹사이트 Rust should have a lower learning curve https://github.com/r[...]
[223] 웹사이트 Miscellany: C++ design goals in the context of Rust https://pcwalton.blo[...]
[224] 웹사이트 Frequently Asked Questions · The Rust Programming Language - How fast is Rust? https://www.rust-lan[...]
[225] 웹사이트 Rust versus C gcc fastest programs| Computer Language Benchmarks Game https://benchmarksga[...]
[226] 웹사이트 Web Framework Benchmarks - Round 15 2018-02-14 https://www.techempo[...] Framework Benchmarks Google Group
[227] 웹사이트 Web Framework Benchmarks - Round 15 2018-02-14 https://www.techempo[...] Framework Benchmarks Google Group
[228] 문서 Graydon Hoare
[229] 웹사이트 Interview on Rust, a Systems Programming Language Developed by Mozilla http://www.infoq.com[...] InfoQ 2012-08-03
[230] 웹사이트 Project FAQ https://github.com/m[...] 2010-09-14
[231] 웹사이트 Rust https://research.moz[...]
[232] 웹사이트 Future Tense http://www.slideshar[...] 2011-04-29
[233] Twitter 2017-03-12
[234] 웹사이트 Rust Progress http://blog.mozilla.[...] 2010-10-02
[235] 웹사이트 rust-dev] stage1/rustc builds https://mail.mozilla[...] 2011-04-20
[236] 웹사이트 A Quick Look at the Rust Programming Language https://bluishcoder.[...] 2011-03-31
[237] 웹사이트 Mozilla and the Rust community release Rust 0.1 (a strongly-typed systems programming language with a focus on memory safety and concurrency) http://www.reddit.co[...] 2012-01-20
[238] 웹사이트 Vale Java? Scala Vala palava http://broadcast.ore[...] 2010-11-08
[239] 웹사이트 Commit dabccadd3202513ab0bcb424e2c62c90ab23062d https://github.com/m[...] 2011-02-26
[240] 논문 Typestate: A Programming Language Concept for Enhancing Software Reliability https://www.cs.cmu.e[...] IEEE Transactions on Software Engineering
[241] 웹사이트 Typestate Is Dead, Long Live Typestate! https://pcwalton.git[...] 2012-12-26
[242] 웹사이트 Removing Garbage Collection From the Rust Language https://pcwalton.git[...] 2013-01-02
[243] 웹사이트 The Rise And Fall of Languages in 2013 https://www.drdobbs.[...]
[244] 웹사이트 Announcing Rust 1.0 - The Rust Programming Language Blog http://blog.rust-lan[...] 2015-05-15
[245] 웹사이트 rfcs/0507-release-channels.md at master · rust-lang/rfcs https://github.com/r[...] 2014-10-27
[246] 웹사이트 Stability as a Deliverable - The Rust Programming Language Blog https://blog.rust-la[...] 2014-10-30
[247] 웹사이트 Scheduling the Trains https://blog.rust-la[...] 2017-01-01
[248] 웹사이트 Firefox リリースノート Firefox 48.0 https://www.mozilla.[...] Mozilla Foundation 2016-08-02
[249] 웹사이트 Firefox に組み込まれた Rust https://dev.mozilla.[...] Mozilla Foundation 2016-08-02
[250] 웹사이트 Rust meets Fedora https://fedoramagazi[...] fedoramagazine.org 2016-09-21
[251] 웹사이트 Announcing Rust 1.31 and Rust 2018 https://blog.rust-la[...] 2018-12-17
[252] 웹사이트 The Plan for the Rust 2021 Edition {{!}} Rust Blog https://blog.rust-la[...] 2021-09-19
[253] 웹사이트 Shipping Rust in Firefox https://hacks.mozill[...] 2018-01-28
[254] 웹사이트 Mozilla's Rust-based Servo browser engine inches forward https://www.infoworl[...] 2018-01-28
[255] 웹사이트 A Quantum Leap for the Web https://medium.com/m[...] 2018-01-28
[256] 웹사이트 Supporting the Use of Rust in the Chromium Project https://security.goo[...] 2023-01-12
[257] 웹사이트 Chromium プロジェクトが Rust の利用をサポート https://developers-j[...] 2023-02-16
[258] 웹사이트 Habitat at RustConf https://blog.chef.io[...] 2018-01-28
[259] 웹사이트 The Epic Story of Dropbox's Exodus From the Amazon Cloud Empire | WIRED https://www.wired.co[...] 2018-01-28
[260] 웹사이트 The Epic Story of Dropbox's Exodus From the Amazon Cloud Empire | WIRED https://www.infoworl[...] 2018-01-28
[261] 웹사이트 intermezzOS: a little OS https://intermezzos.[...] 2018-01-28
[262] 웹사이트 Red Hat deprecates BTRFS, is Stratis the new ZFS-like hope? https://www.marksei.[...] 2018-01-28
[263] 뉴스 Building a Container Runtime in Rust https://blogs.oracle[...] 2017-06-29
[264] 웹사이트 グーグル、Rust採用で「Android」のメモリーに関わる脆弱性が激減 https://japan.zdnet.[...] ZDNet Japan 2022-12-06
[265] 웹사이트 「Linux」、バージョン6.1でRustを導入へ--トーバルズ氏が明言 https://japan.zdnet.[...] ZDNET 2022-10-18
[266] 웹사이트 グーグル、Rustで書かれたセキュアなOS「KataOS」を発表 https://japan.cnet.c[...] CNET Japan 2022-10-18
[267] 웹사이트 Microsoft、Windows 10の一部をRustへ書き換えてセキュリティ強化狙う https://news.mynavi.[...] マイナビ 2022-12-07
[268] 웹사이트 As Blockchain Changes The World, Bitfury’s New Platform Exonum is About to Change Blockchain https://medium.com/@[...] 2018-01-28
[269] 서적 Rust Essentials https://books.google[...] Packt Publishing 2016-03-21
[270] 웹사이트 Using HyperLogLog to Detect Malware Faster Than Ever https://labs.opendns[...] 2016-03-19
[271] 웹사이트 ZeroMQ: Helping us Block Malicious Domains in Real Time https://labs.opendns[...] 2016-03-19
[272] 웹사이트 Piston A modular game engine written in Rust http://www.piston.rs[...] 2017-08-01
[273] 웹사이트 ctz/rustls: A modern TLS library in Rust https://github.com/c[...] 2018-02-04
[274] 웹사이트 Remacs:Re-Implementing Emacs In Rust https://www.phoronix[...] 2017-01-11
[275] 웹사이트 Pijul https://pijul.org/ 2017-07-08
[276] 웹사이트 xi-editor https://opensource.g[...] 2018-01-28
[277] 웹사이트 ripgrep is faster than {grep, ag, git grep, ucg, pt, sift} https://blog.burntsu[...] 2018-01-28
[278] 웹사이트 rav1e: The fastest and safest AV1 encoder. https://github.com/x[...] 2018-05-01
[279] 웹사이트 Parity’s Polkadot Dev Update #2 https://medium.com/p[...] 2018-12-05
[280] 웹사이트 mirakc: A Mirakurun-compatible PVR backend written in Rust https://github.com/m[...] 2020-08-10
[281] 웹사이트 Dropbox、4年をかけてRust言語で再構築された新しい同期エンジン「Nucleus」をリリース https://forest.watch[...] Impress 2022-12-07
[282] 웹인용 Doc language FAQ https://github.com/m[...] 2013-04-29
[283] 웹인용 Project FAQ https://github.com/m[...] 2012-01-11
[284] 웹인용 Future Tense http://www.slideshar[...] 2012-02-06
[285] 웹인용 Rust Progress http://blog.mozilla.[...] 2010-10-30
[286] 웹인용 Mozilla and the Rust community release Rust 0.1 (a strongly-typed systems programming language with a focus on memory safety and concurrency) http://www.reddit.co[...] 2012-02-06
[287] 웹인용 The Mozilla Manifesto http://www.mozilla.o[...] 2013-04-29
[288] 문서 러스트공식가이드 https://jpub.tistory[...]
[289] 문서 The Rust Programming Language,Nicholas Matsakis와 Aaron Turon https://rinthel.gith[...]
[290] 웹인용 美 국가안보국, C/C++ 대신 러스트·고·C# 사용 권고 https://n.news.naver[...] 2022-11-22
[291] URL https://hacks.mozill[...]
[292] URL http://www.wired.com[...]
[293] 뉴스 Mozilla's Rust-based Servo browser engine inches forward http://www.infoworld[...] 2015-04-03
[294] 뉴스 Mozilla And Samsung Team Up To Develop Servo, Mozilla’s Next-Gen Browser Engine For Multicore Processors http://techcrunch.co[...] 2015-04-03
[295] 서적 Rust Essentials https://books.google[...] Packt Publishing 2016-03-21
[296] 웹인용 Using HyperLogLog to Detect Malware Faster Than Ever https://labs.opendns[...] 2016-03-19
[297] 웹인용 ZeroMQ: Helping us Block Malicious Domains in Real Time https://labs.opendns[...] 2016-03-19
[298] 뉴스 Rust's Redox OS could show Linux a few new tricks http://www.infoworld[...] infoworld 2016-03-21
[299] URL https://github.com/p[...]
[300] URL http://www.piston.rs[...]
[301] 웹인용 Why Discord is switching from Go to Rust https://blog.discord[...] 2020-04-14
[302] 문서 러스트 - 플레이그라운드 https://play.rust-la[...]
[303] 문서 Rust Foundation - official site https://foundation.r[...]

관련 사건 타임라인

( 최근 20개의 뉴스만 표기 됩니다. )



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com